perm filename LISP.WD[S,DOC] blob
sn#202031 filedate 1976-02-17 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00108 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00016 00002
C00017 00003 STANFORD ARTIFICIAL INTELLIGENCE LABORATORY
C00019 00004 SAILON 28.7 LISP i
C00020 00005 SAILON 28.7 LISP ii
C00022 00006 SAILON 28.7 LISP iii
C00026 00007 SAILON 28.7 LISP iv
C00030 00008 SAILON 28.7 LISP v
C00032 00009 SAILON 28.7 CHAPTER 1 1-1
C00035 00010 SAILON 28.7 CHAPTER 1 1-2
C00038 00011 SAILON 28.7 CHAPTER 1 1-3
C00041 00012 SAILON 28.7 Document Conventions 1.4-1
C00044 00013 SAILON 28.7 Document Conventions 1.4-2
C00045 00014 SAILON 28.7 CHAPTER 2 2-1
C00048 00015 SAILON 28.7 CHAPTER 2 2-2
C00050 00016 SAILON 28.7 CHAPTER 3 3-1
C00053 00017 SAILON 28.7 CHAPTER 3 3-2
C00056 00018 SAILON 28.7 CHAPTER 3 3-3
C00060 00019 SAILON 28.7 CHAPTER 3 3-4
C00061 00020 SAILON 28.7 CHAPTER 4 4-1
C00064 00021 SAILON 28.7 CHAPTER 4 4-2
C00067 00022 SAILON 28.7 CHAPTER 4 4-3
C00069 00023 SAILON 28.7 CHAPTER 5 5-1
C00071 00024 SAILON 28.7 CHAPTER 6 6-1
C00075 00025 SAILON 28.7 CHAPTER 6 6-2
C00078 00026 SAILON 28.7 CHAPTER 6 6-3
C00081 00027 SAILON 28.7 CHAPTER 6 6-4
C00083 00028 SAILON 28.7 CHAPTER 7 7-1
C00086 00029 SAILON 28.7 CHAPTER 7 7-2
C00089 00030 SAILON 28.7 CHAPTER 7 7-3
C00093 00031 SAILON 28.7 CHAPTER 7 7-4
C00097 00032 SAILON 28.7 CHAPTER 8 8-1
C00099 00033 SAILON 28.7 CHAPTER 9 9-1
C00102 00034 SAILON 28.7 CHAPTER 9 9-2
C00105 00035 SAILON 28.7 CHAPTER 9 9-3
C00108 00036 SAILON 28.7 CHAPTER 10 10-1
C00111 00037 SAILON 28.7 CHAPTER 10 10-2
C00114 00038 SAILON 28.7 CHAPTER 10 10-3
C00117 00039 SAILON 28.7 CHAPTER 10 10-4
C00120 00040 SAILON 28.7 CHAPTER 10 10-5
C00122 00041 SAILON 28.7 CHAPTER 10 10-6
C00125 00042 SAILON 28.7 CHAPTER 10 10-7
C00127 00043 SAILON 28.7 CHAPTER 11 11-1
C00131 00044 SAILON 28.7 CHAPTER 11 11-2
C00134 00045 SAILON 28.7 CHAPTER 11 11-3
C00136 00046 SAILON 28.7 CHAPTER 12 12-1
C00139 00047 SAILON 28.7 CHAPTER 12 12-2
C00141 00048 SAILON 28.7 CHAPTER 12 12-3
C00143 00049 SAILON 28.7 CHAPTER 13 13-1
C00146 00050 SAILON 28.7 CHAPTER 14 14-1
C00150 00051 SAILON 28.7 CHAPTER 14 14-2
C00154 00052 SAILON 28.7 CHAPTER 14 14-3
C00158 00053 SAILON 28.7 CHAPTER 14 14-4
C00161 00054 SAILON 28.7 CHAPTER 14 14-5
C00164 00055 SAILON 28.7 CHAPTER 14 14-6
C00166 00056 SAILON 28.7 CHAPTER 15 15-1
C00169 00057 SAILON 28.7 CHAPTER 15 15-2
C00172 00058 SAILON 28.7 CHAPTER 16 16-1
C00175 00059 SAILON 28.7 CHAPTER 16 16-2
C00178 00060 SAILON 28.7 APPENDIX A A-1
C00182 00061 SAILON 28.7 APPENDIX A A-2
C00185 00062 SAILON 28.7 APPENDIX A A-3
C00188 00063 SAILON 28.7 APPENDIX A A-4
C00191 00064 SAILON 28.7 APPENDIX A A-5
C00193 00065 SAILON 28.7 APPENDIX A A-6
C00195 00066 SAILON 28.7 APPENDIX B B-1
C00198 00067 SAILON 28.7 APPENDIX B B-2
C00201 00068 SAILON 28.7 APPENDIX B B-3
C00204 00069 SAILON 28.7 APPENDIX B B-4
C00206 00070 SAILON 28.7 APPENDIX C C-1
C00209 00071 SAILON 28.7 APPENDIX C C-2
C00212 00072 SAILON 28.7 APPENDIX C C-3
C00214 00073 SAILON 28.7 APPENDIX D D-1
C00217 00074 SAILON 28.7 APPENDIX E E-1
C00220 00075 SAILON 28.7 APPENDIX E E-2
C00223 00076 SAILON 28.7 APPENDIX E E-3
C00227 00077 SAILON 28.7 APPENDIX E E-4
C00229 00078 SAILON 28.7 APPENDIX F F-1
C00233 00079 SAILON 28.7 APPENDIX F F-2
C00237 00080 SAILON 28.7 APPENDIX F F-3
C00241 00081 SAILON 28.7 APPENDIX F F-4
C00244 00082 SAILON 28.7 APPENDIX F F-5
C00246 00083 SAILON 28.7 APPENDIX G G-1
C00249 00084 SAILON 28.7 APPENDIX G G-2
C00250 00085 SAILON 28.7 APPENDIX H H-1
C00254 00086 SAILON 28.7 APPENDIX H H-2
C00257 00087 SAILON 28.7 APPENDIX H H-3
C00258 00088 SAILON 28.7 APPENDIX I I-1
C00260 00089 SAILON 28.7 APPENDIX J J-1
C00264 00090 SAILON 28.7 APPENDIX J J-2
C00267 00091 SAILON 28.7 APPENDIX J J-3
C00269 00092 SAILON 28.7 APPENDIX K K-1
C00273 00093 SAILON 28.7 APPENDIX L L-1
C00276 00094 SAILON 28.7 APPENDIX M M-1
C00279 00095 SAILON 28.7 APPENDIX M M-2
C00281 00096 SAILON 28.7 APPENDIX N N-1
C00284 00097 SAILON 28.7 APPENDIX N N-2
C00285 00098 SAILON 28.7 APPENDIX O O-1
C00288 00099 SAILON 28.7 APPENDIX O O-2
C00290 00100 SAILON 28.7 APPENDIX P P-1
C00292 00101 SAILON 28.7 APPENDIX P P-2
C00294 00102 SAILON 28.7 APPENDIX P P-3
C00296 00103 SAILON 28.7 APPENDIX P P-4
C00297 00104 SAILON 28.7 REFERENCES REF-1
C00298 00105 SAILON 28.7 INDEX IND-1
C00303 00106 SAILON 28.7 INDEX IND-2
C00308 00107 SAILON 28.7 INDEX IND-3
C00313 00108 SAILON 28.7 INDEX IND-4
C00317 ENDMK
C⊗;
STANFORD ARTIFICIAL INTELLIGENCE LABORATORY
OPERATING NOTE 28.7
STANFORD LISP 1.6 MANUAL
by
Lynn H. Quam and Whitfield Diffie
ABSTRACT: This manual describes the PDP-10 LISP 1.6 system developed by
the Stanford Artificial Intelligence Project. The manual is
not a tutorial on LISP but is intended to supplement existing
LISP tutorials in order to prepare one to understand and use
this LISP system.
This work was supported by the Advanced Research Projects Agency of the
Department of Defense under Contract SD-183.
The views and conclusions contained in this document are those of the
authors and should not be interpreted as necessarily representing the
official policies, either expressed or implied, of the Advanced
Research Projects Agency or the U.S. Government.
SAILON 28.7 LISP i
PREFACE
This manual is the result of several relatively minor changes
and additions to SAILON 28.4. It supercedes and replaces SAILONS 1,
4, 28.2-4, and 41.
The changes reflect changes in LISP and may be summarized as
follows:
LISP initialization has changed; Section 2.1.
There are some new debugging facilities in Appendix N and the
documentation for some old ones has been put into the manual.
The compiler has been revised, and is described in a greatly
expanded Appendix F.
SAILON 28.7 LISP ii
Acknowledgment
The STANFORD A.I. Lisp 1.6 System was originally an
adaptation of one developed by the Artificial Intelligence Project at
M.I.T. Since 1966, that system has been largely rewritten by John
Allen and Lynn Quam.
John R. Allen implemented the storage reallocation system
which makes it possible for the user to change the sizes of the
various memory spaces. He also designed and coded the editor ALVINE,
wrote the first loader interface, and generally maintained and
debugged the system. John Allen contributed the ALVINE
documentation in Appendix A.
Marilyn Mullins has assisted in the preparation of the
present edition.
SAILON 28.7 LISP iii
TABLE OF CONTENTS
Page
Preface................................................. i
Acknowledgment ......................................... ii
Table of Contents....................................... iii
CHAPTER
1. INTRODUCTION...................................... 1-1
1.1 Guide to the Novice........................... 1-1
1.2 Guide to the User Experienced with Another
LISP System............................. 1-2
1.1 Guide to Useful Functions and Features........ 1-3
1.4 Document Conventions.......................... 1-4
2. INTERACTIVE USE OF THE SYSTEM .................... 2-1
2.1 Using the System ............................. 2-1
2.2 Special Teletype Control Characters........... 2-1
3. IDENTIFIERS ...................................... 3-1
3.1 Property Lists................................ 3-2
3.2 The OBLIST.................................... 3-3
3.3 Strings....................................... 3-3
4. NUMBERS............................................ 4-1
4.1 Integers...................................... 4-1
4.2 Reals......................................... 4-3
5. S-EXPRESSIONS...................................... 5-1
6. LAMBDA EXPRESSIONS................................. 6-1
6.1 EXPRs and SUBRs............................... 6-2
6.2 FEXPRs AND FSUBRs............................. 6-2
6.3 LEXPRs AND LSUBRs............................. 6-2
6.4 MACROs........................................ 6-3
7. EVALUATION OF S-EXPRESSIONS........................ 7-1
7.1 Variable Bindings............................. 7-2
7.2 The A-LIST and FUNARG Features................ 7-3
8. CONDITIONAL EXPRESSIONS............................ 8-1
SAILON 28.7 LISP iv
9. PREDICATES......................................... 9-1
9.1 S-Expression Predicates....................... 9-2
9.2 Numerical Predicates.......................... 9-2
9.3 Boolean Predicates............................ 9-3
10. FUNCTIONS ON S-EXPRESSIONS.........................10-1
10.1 S-Expression Building Functions...............10-1
10.2 S-Expression Fragmenting Functions............10-2
10.3 S-Expression Modifying Functions.............10-2
10.4 S-Expression Transforming Functions...........10-4
10.5 S-Expression Mapping Functions................10-4
10.6 S-Expression Searching Functions..............10-6
10.7 Character List Transforming Functions.........10-7
11. FUNCTIONS ON IDENTIFIERS...........................11-1
11.1 Property List Functions.......................11-1
11.2 OBLIST Functions..............................11-2
11.3 Identifier Creating Functions.................11-3
12. FUNCTIONS ON NUMBERS...............................12-1
12.1 Arithmetic Functions..........................12-1
12.2 Logical Functions.............................12-2
13. PROGRAMS...........................................13-1
14. INPUT/OUTPUT.......................................14-1
14.1 File Names....................................14-1
14.2 Channel Names.................................14-1
14.3 Input.........................................14-1
14.4 Output........................................14-4
15. ARRAYS.............................................15-1
15.1 Examine and Deposit...........................15-2
16. OTHER FUNCTIONS....................................16-1
APPENDIX A. ALVINE - by John Allen..................... A-1
APPENDIX B. ERROR MESSAGES............................. B-1
APPENDIX C. MEMORY ALLOCATION.......................... C-1
APPENDIX D. GARBAGE COLLECTION......................... D-1
APPENDIX E. COMPILED FUNCTION LINKAGE AND ACCUMULATOR
USAGE................................... E-1
APPENDIX F. THE LISP COMPILER.......................... F-1
APPENDIX G. THE LISP ASSEMBLER - LAP................... G-1
APPENDIX H. THE LOADER................................. H-1
APPENDIX I. BIGNUMS - ARBITRARY PRECISION INTEGERS..... I-1
SAILON 28.7 LISP v
APPENDIX J. A USER MODIFIABLE LISP SCANNER............. J-1
APPENDIX K. SOS-LINK................................... K-1
APPENDIX L. SOME DIFFERENCES BETWEEN THIS AND OTHER
LISPS................................... L-1
APPENDIX M, LISP DISPLAY PRIMITIVES.................... M-1
APPENDIX N. TRACE...................................... N-1
APPENDIX O. SMILE ..................................... O-1
APPENDIX P. CONSTRUCTION OF A LISP DISK-DECTAPE SYSTEM..P-1
REFERENCES.............................................REF-1
INDEX..................................................IND-1
SAILON 28.7 CHAPTER 1 1-1
CHAPTER 1
INTRODUCTION
This manual is intended to explain the interactive LISP 1.6
system which has been developed for the PDP-10 at the Stanford
University Artificial Intelligence Project. It is assumed that the
reader is familiar with either some other LISP system or the LISP 1.5
PRIMER by Clark Weissman[2].
The LISP 1.6 system described has as a subset most of the
features and functions of other LISP 1.5 systems. In addition, there
are several new features such as an arbitrary precision integer
package, an S-expression editor, up to 14 active input-output
channels, the ability to control the size of memory spaces, a
standard relocating loader to load assembly language or compiled
programs, etc.
This system uses an interpreter; however, there is also a
compiler which produces machine code. Compiled functions are
approximately 20 times as fast and take less memory space.
This manual is organized in a functional manner. First the
basic data structures are described; then the functions for operating
on them. The appendices present more detailed information on the
system, its internal structure, the compiler, and several auxiliary
packages.
SAILON 28.7 CHAPTER 1 1-2
1.1 Guide to the Novice
The user who is not experienced with any LISP system is
advised to follow the instructions below:
1) Become familiar with Weissman's LISP 1.6 Primer[2] or some
equivalent introductory LISP Manual.
2) Learn the document conventions (1.4).
3) Become superficially familiar with LISP 1.6 identifiers,
numbers and S-expressions (Chapters 3,4, and 5).
4) Understand the most useful functions: Those preceded by
exclamation marks "!" in chapters 6 through 14.
5) Learn how to define functions (6.1).
6) Learn how to interact with LISP (Chapter 2).
7) Try some examples. Weissman[1] has some good problems.
8) Learn what other useful functions and features are
available (1.3).
1.2 Guide to the User Experienced with Another LISP System
The user who has used another LISP system is advised to
follow these instructions:
1) Learn the document conventions (1.4).
2) Learn top level of LISP 1.6 is EVAL, not EVALQUOTE.
3) Use DE, DF and DEFPROP for defining functions. (Section 11.1).
4) Many functions differ from those in other systems. Most
of these are noted in the index.
5) The syntax of atoms is different from other systems
(Chapters 3 and 4).
6) Learn how to interact with LISP (Chapter 2).
7) Try some examples.
8) Learn what other useful functions and features are
available (1.3).
SAILON 28.7 CHAPTER 1 1-3
1.3 Guide to Useful Functions and Features
The following is a partial list of useful features and functions in
LISP 1.6 and what they might be useful for.
1) ALVINE (Appendix A) is useful for editing functions and
manipulating I/O files.
2) READ has some very useful control characters (Section 14.3).
3) Input/Output (Chapter 14) is very flexible.
4) One can control error messages (Chapter 16).
5) There is a LISP compiler (Appendix F) which generates code
that runs approximately twenty times as fast as interpreted
functions.
6) There are auxiliary files on the disk which are often useful:
filename use document
SYS:SMILE file manipulation Appendix O
SYS:TRACE tracing functions Appendix N
and setqs
SYS:SOSLNK rapid turn-around Appendix K
between SOS and LISP
SYS:LISPDP.LSP III display functions Appendix M
LISP.COR[S,DOC] corrections to this
manual
7) One can load and link LISP to assembly and Fortran
compiled programs. See Appendix H.
8) One can have files automatically loaded by use of
the file INIT.LSP which is automatically loaded
on entry.
SAILON 28.7 Document Conventions 1.4-1
1.4 Document Conventions
1.4.1 Representation Conventions
In the description of data structures, the following
notational conventions will be used.
_________________ represents a 36-bit word in
| | | FREE STORAGE with 2 18-bit
| | |-→ pointers.
|_______|_______|
↓
_________________ represents the last word in
| | | a list.
| | NIL | →
|_______|_______|
↓
_________________ represents a 36-bit word in
| | FULL WORD SPACE.
| |
|_______________|
1.4.2 Syntax Conventions
A slightly modified form of BNF is used to define syntax
equations. Optional terms are surrounded by curly brackets { and }.
1.4.3 Calling Sequence Conventions
Calling sequences to LISP functions are presented in
S-expression form, with the CAR of the S-expression being the name of
the function. An argument to a function is evaluated unless that
argument is surrounded by quotes (") in the calling sequence
definition. Quotes mean that the function implicitly QUOTEs that
argument.
Examples: (SETQ "ID" V) ID is not evaluated, but V is
evaluated.
(QUOTE "V") V is not evaluated.
1.4.4 Other Conventions
The blank character (ASCII 40) is indicated by "_" when
appropriate for clarity. The delimiters altmode, carriage return,
linefeed and space will sometimes be represented as <alt>, <cr>, <lf>
and <sp>.
SAILON 28.7 Document Conventions 1.4-2
A special notation in the left margin is used to indicate the
degree of utility or difficulty of each section of this manual:
mark meaning
! basic
<no mark> generally useful
* useful but more sophisticated
# not generally useful
SAILON 28.7 CHAPTER 2 2-1
CHAPTER 2
INTERACTIVE USE OF THE SYSTEM
2.1 Using the System
The following dialog shows how to log into the time sharing
system, start the LISP system, and interact with the top level of
LISP. The period, sharp sign and askerisk are typed by the system,
login and lisp respectively to indicate that they are waiting for the
user to type.
.L
#1,FOO
↑C
.R LISP 20 This give a 20K Lisp instead of the usual 12K.
ALLOC? Y Indicates that the user will specify
the sizes of the various spaces.
FULL WDS=<sp> This gives the default value.
BIN.PROG.SP=12000<sp> This gives 12K of Binary Program Space.
SPEC.PDL=<sp> This give the default value.
SPEC.PDL=2000<sp> Gives 2K of regular push down list.
HASH=177<sp> Makes the length of the OBLIST 177.
For a full discussion of allocation see Appendix C.
Digression:
At this point, after allocation and before anything else, the
file LISP.LSP is read from the system. This defines various macros,
recent additions to the system, bootstrap definitions for the
functions in the various self loading utility files, Trace, SOSLNK,
LAP etc. In addition, if there is a file by the name LISP.INI in the
user's directory, it will be loaded too. This enables the user to
have anything he likes loaded automatically.
To continue:
*T<alt>
T T and NIL always evaluate to themselves.
*(QUOTE (A B C))<cr>
(A B C) Value of QUOTE
*(CONS 1 (QUOTE A))<cr>
(1 . A) Numbers always evaluate to themselves
and thus need not be quoted.
*(DSKIN <random file name>)<cr> Reads and evaluates each expression
in the file.
<a long sequence of output> This output can be suppressed with ↑O.
SAILON 28.7 CHAPTER 2 2-2
*(DEFPROP CDRQ (LAMBDA (L) (CDAR L)) FEXPR)<cr>
CDRQ
*(CDRQ CAR)<cr>
(SUBR #address PNAME (#fullword))
*(DE TWICE (NUM) (TIMES 2 NUM))<cr>
TWICE
*(TWICE 3)<cr>
6
<etc.>
2.2 Special Teletype Control Characters
The time-sharing system treats many control characters in special
ways. For a complete discussion of control characters see the PDP-10
TIME SHARING MONITOR MANUAL. Briefly, the following special control
characters are used in LISP.
Teletype III Display Meaning
↑C CALL Stop the job and talk to
time-sharing system.
↑O Control 2 Suppress console printout
linefeed until an input is requested.
↑U Control 1 Delete the entire input
linefeed line now being typed.
(Only with (DDTIN NIL)).
↑G(BELL) π Stop the LISP interpreter
and return control to the
top level of LISP. Only
effective when LISP is
asking for console input.
See INITFN (16).
rubout BS Delete the last character
typed. (For (DDTIN T) see
14-3.
SAILON 28.7 CHAPTER 3 3-1
CHAPTER 3
IDENTIFIERS
Identifiers are strings of characters which taken together
represent a single atomic quantity.
Syntax:
<comments> ::=<ASCII 32> <any sequence of characters not
including line-feed> <line feed>
<delimiter> ::= (|) | [|] | ? |@|/|"| <blank> | <altmode> |
carriage-return | <line-feed> | <tab> | <form-
feed>
<character>::= <any extended ASCII character other than null
and ASCII 176>
<digit>::= 0|1|2|3|4|5|6|7|8|9
<letter>::= <any character not a digit and not a delimiter>
<identifier>::= <letter>
::=<identifier> <digit>
::= / <character>
::= <identifier>/<character>
Semantics:
Identifiers are normally strings of characters beginning with
a letter and followed by letters and digits. It is sometimes
convenient to create identifiers which contain delimiters or begin
with digits. The use of the delimiter "/" (slash) causes the
following character be taken literally, and the slash itself is not
part of the identifier. Thus, /AB is the same as AB is the same as
/A/B.
Comments are useful for allowing descriptive text in files
which will be completely ignored when read. Comments also make it
possible to extend atoms (identifiers, strings and numbers) across
line boundaries without any of the characters in the comment becoming
part of the atom.
ASCII 32 cannot be typed directly into LISP. In STOPGAP, ?3
designates ASCII 32. On the line printer and III displays, ASCII 32
prints as tilde "~". ASCII 32 does not print on teletypes. (See
CHRCT in 14.1.4.)
Examples: A /(
a ?
FOObaz /13245
TIME-OF-DAY /,
A1B2 LPT:
Representation:
SAILON 28.7 CHAPTER 3 3-2
An identifier is internally represented as a dotted pair of
the following form:
___________
identifier → | -1 | | → property list
|____|____|
which is called an atom header.
Thus CDR of an identifier gives the property list of the
identifier, but CAR of an identifier gives the pointer 777777, which
if used as an address will cause an illegal memory reference, and an
error message. An identifier is referred to in symbolic computation
by the address of its atom header.
3.1 Property Lists
The property list of an identifier is a list of pairs:
(property name, property value) associated with that identifier. The
normal kinds of properties which are found in property lists are
print names, values, and function definitions corresponding to
identifiers.
3.1.1 Print Names
Every identifier has a print name (PNAME) on its property
list. The print name of an identifier is a list of full words, each
containing five ASCII characters.
Example: The identifier TIME-OF-DAY would be initially represented
as follows:
__________ _________ _________
atom → | -1 | | → | | | → | |NIL|
header |____|___| |___|___| |___|___|
↓ ↓
_________ _________ _________
atom | | | | | | | |NIL|
"PNAME" |___|___| |___|___| |___|___|
↓ ↓ ↓
_________ _________ _________
| TIME- | | OF-DA | | Y∧∧∧∧ |
|_______| |_______| |_______|
where ∧ means null or ASCII 0.
SAILON 28.7 CHAPTER 3 3-3
3.1.2 Special Cells
When a value is assigned an identifier, the property name
VALUE is put on the identifier's property list with property value
being a pointer to a special cell. The CDR of the special cell
(sometimes called VALUE cell) holds the value of the identifier, and
the address of a special cell remains constant for that identifier
unless REMPROPed (11.2), to enable compiled functions to directly
reference the values of special variables. Global variables and all
variables bound in interpreted functions store their values in
special cells.
Example: The atom NIL has the following form:
atom header property list
_________ __________ _________ __________ _________
| -1| |→|VALUE| |→| | |→|PNAME| |→| |NIL|
|___|___| |_____|__| |___|___| |_____|__| |___|___|
↑ ↓ ↓
| special _________ _________
| cell |NIL|NIL| print | |NIL|
| |___|___| name |___|___|
|________________________|
↓
_________
| NIL∧∧ |
|_______|
3.2 The OBLIST
In order that occurrences of identifiers with the same print
names have the same internal address (and hence value), a special
list which is the VALUE of a global variable called OBLIST is used to
remember all identifiers which READ and some other functions have
seen. For the sake of searching efficiency, this list has two
levels; the first level contains sequentially stored "buckets" which
are "hashed" into as a function of the print name of the identifier.
Each bucket is a list of all distinct identifiers which have hashed
into that bucket. Thus, (CAR OBLIST) is the first bucket, and (CAAR
OBLIST) is the first identifier of the first bucket.
3.3 Strings
Syntax:
string::= "<any sequence of characters not containing ">"
Semantics
SAILON 28.7 CHAPTER 3 3-4
A string is an arbitrary sequence of characters surrounded by
double quotes and not containing double quotes. Strings are
represented identically to identifiers except that strings are not
automatically INTERNed on the OBLIST. The double quotes surrounding
strings actually become part of the PRINT NAME of the string unlike
slashes in slashified identifiers.
Examples:
"I AM A STRING"
"1,3-X 5"
SAILON 28.7 CHAPTER 4 4-1
CHAPTER 4
NUMBERS
There are two syntactic types of numbers: integer and real.
<number> ::= <integer> | <real>
4.1 Integers
Syntax:
<integer> ::= {<sign>} <digits> {*}
<digits> ::= <digit> {<digits>}
<sign> ::= +|-
Semantics:
The global variable IBASE specifies the input radix for
integers which are not followed by "." Integers followed by "." are
decimal integers. IBASE is initially = 8. Similarly, the global
variable BASE controls output radix for integers. If BASE = 10 then
integers will print with a following ".", unless the global variable
*NOPOINT = T.
Examples with IBASE = 8
input meaning
-13 = -11 = -11↓10
1000 = 512 =+512↓10
19 = 17 = +17↓10
Representation:
There are three representations for integers depending on the
numerical magnitude of the integer: INUM, FIXNUM, and BIGNUM. Their
ranges are as follows:
INUM |n| <K K is usually 2↑16
FIXNUM K≤ |n| <2↑35
BIGNUM 2↑35 ≤ |n|
Representation of INUMs:
INUMs are small integers represented by pointers outside of
the normal LISP addressing space. INUMs are addresses in the range
2↑18-2K to 2↑18-2. The INUM representation for zero is α = 2↑18-K-1.
SAILON 28.7 CHAPTER 4 4-2
Examples INUM Representation
-(K-1) α - (K-1)
-1 α - 1
0 α = 2↑18-K-1
1 α + 1
K-1 α + K-1
Representation of FIXNUMs:
FIXNUMs are represented by list structure of the following form:
Atom header
________ ___________ _________
| -1| |→ |FIXNUM| |→ | value |
|___|__| |______|___| |_______|
where value is the 2's complement representation of the fixed point
number.
Examples:
________ ___________ _____________
+100000000↓8 | -1| |→ |FIXNUM| |→ |000100000000|
|___|__| |______|___| |____________|
________ ___________ _____________
-1400000032↓8 | -1| |→ |FIXNUM| |→ |776377777746|
|___|__| |______|___| |____________|
Representation of BIGNUMs
BIGNUMs are represented by list structure of the following forms:
________ ___________ _________ _________
Positive BIGNUMs → | -1| |→ |POSNUM| |→ | | |→ | |NIL|
|___|__| |______|___| |___|___| |___|___|
↓ ↓
_________ _________
| N0 | | Nn |
|_______| |_______|
________ ___________ _________ _________
Negative BIGNUMs → | -1| |→ |NEGNUM| |→ | | |→ | |NIL
|___|__| |______|___| |___|___| |___|___|
↓ ↓
_________ _________
| N0 | | Nn |
|_______| |_______|
SAILON 28.7 CHAPTER 4 4-3
where N↓i are positive 36 bit integers ordered from least to most
significant. The value of a BIGNUM is
sign * (N↓0 + 2↑35 N, + 2↑35*2 N↓2 + ... + 2↑35n N↓n)
Note: BIGNUMs are not normally a part of the interpreter. Appendix H
describes the procedures for loading the BIGNUM package.
4.2 Reals
Syntax:
<real> ::= {<sign>} <digits> {*} <exponent>
::= {<sign>} {<digits>} * <digits> {<exponent>}
<exponent> ::= E {<sign>} <digits>
Examples:
meaning
3.14159 +3.14159
+1E-3 +0.001
-196.37E4 -1963700.0
0.3 +0.3
-0.3E+1 -3.0
Restrictions:
The radix for real numbers is always decimal. A real number x
must be in the (approximate) range:
10↑-38 < |x| < 10↑+38 or x = 0
A real number has approximately eight significant digits of accuracy.
Representation:
atom header
__________ _______________ _________
| -1 | | → |FLONUM| | → | value |
|____|___| |______|______| |_______|
where value is in PDP-6/10 2's complement floating point
representation.
SAILON 28.7 CHAPTER 5 5-1
CHAPTER 5
S-EXPRESSIONS
Syntax:
<atom> ::= <identifier> | <string> | <number>
<S-expression> ::= <atom>
::= (<S-expression list>{*<S-expression>})
::= ( ) = NIL
<S-expression list> ::= <S-expression>
::= <S-expression> <S-expression list>
Representation:
S-expression representation
_________
(A . (B . C)) → | A | |
|___|___|
↓
_________
| B | C |
|___|___|
_________ _________ _________
((A . B) (C . D) E) → | | | → | | | → | E |NIL|
|___|___| |___|___| |___|___|
↓ ↓
_________ _________
| A | B | | C | D |
|___|___| |___|___|
_________ _________
(A B . C) → | A | | → | B | C |
|___|___| |___|___|
Exceptions:
The identifier NIL is the identifier which represents the
empty list, i.e., ().
SAILON 28.7 CHAPTER 6 6-1
CHAPTER 6
LAMBDA EXPRESSIONS
LAMBDA expressions provide the means of constructing
computational procedures (often called functions, subroutines, or
procedures) which compute answers when values are assigned to their
parameters. A LAMBDA expression can be bound to an identifier so
that any reference to that identifier in functional context refers to
the LAMBDA expression. In LISP 1.6 there are several types of
function definition which determine how arguments are bound to the
LAMBDA expression. The following is a LAMBDA expression:
! (LAMBDA "ARGUMENT-LIST" "BODY")
LAMBDA defines a function by specifying an ARGUMENT-LIST,
which is a list of identifiers (except for LEXPRs, see 6.3) and a
BODY, which is an S-expression. LAMBDA expressions may have no more
than five arguments if they are to be compiled.
Examples: (LAMBDA NIL 1)
This LAMBDA expression of no arguments always
evaluates to one.
(LAMBDA (X) (TIMES X X))
This LAMBDA expression computes the square of
its argument, if x is a number. Otherwise an error
will result.
# (LABEL "ID" "LAMBDA-EXPR")
LABEL creates a temporary name ID for its LAMBDA expression.
This makes it possible to construct recursive functions with
temporary names.
Example:
(DE REVERSE (L)
((LABEL REVEVSE1
(LAMBDA (L M)
(COND ((ATOM L) M)
(T (REVERSE1 (CDR L) (CONS (CAR L) M))))))
L NIL))
LAMBDA expressions are evaluated by "binding" actual
arguments to dummy variables of the LAMBDA expression, (see Chapter
14) then evaluating the body inside the LAMBDA expression with the
current dummy variable bindings. However, actual arguments to LAMBDA
expressions are handled in a variety of ways. Normally, there is a
one-to-one correspondence between dummy variables and actual
arguments, and the actual arguments are evaluated before they are
SAILON 28.7 CHAPTER 6 6-2
bound. However, there are three special forms of function definition
which differ in their handling of actual arguments.
! 6.1 EXPRs and SUBRs
An EXPR is an identifier which has a LAMBDA expression on its
property list with property name EXPR. EXPRs are evaluated by
binding the values of the actual arguments to their corresponding
dummy variables. DE (see 11.1) is useful for defining EXPRs. The
compiled form of an EXPR is a SUBR.
Examples:
(DE SQUARE (X) (TIMES X X))
(DE *MAX (X Y) (COND ((GREATERP X Y) X) (T Y)))
6.2 FEXPRs and FSUBRs
A FEXPR is an identifier which has a LAMBDA expression of one
dummy variable on its property list with property name FEXPR. FEXPRs
are evaluated by binding the actual argument list to the dummy
variable without evaluating any arguments. DF (see 11.1) is useful
for defining FEXPRs. The compiled form of an FEXPR is an FSUBR.
Examples:
(DF LISTQ (L) L)
(LISTQ A (B) C) = (A (B) C)
(LISTQ) = NIL
(DF DEFINE (L)
(MAPC (FUNCTION (LAMBDA (X) (PUTPROP (CAR X)
(CADR X)
(QUOTE EXPR))))
L))
(DEFINE (LEQ (LAMBDA (X Y) (OR (LESSP X Y)
(EQUAL X Y))))
(GEQ (LAMBDA (X Y) (OR (GREATERP X Y)
(EQUAL X Y)))))
# 6.3 LEXPRs and LSUBRs
An LEXPR is an EXPR whose LAMBDA expression has an atomic
argument "list" of the form:
(LAMBDA "ID" "FORM")
LEXPRs may take an arbitrary number of actual arguments which are
evaluated and referred to by the special function ARG. ID is bound
to the number of arguments which are passed. The compiled form of an
LEXPR is an LSUBR.
(ARG N)
SAILON 28.7 CHAPTER 6 6-3
ARG returns the value of the Nth argument to an LEXPR.
Example:
(DE MAX N
(PROG (M)
(SETQ M (ARG N))
L (SETQ N (SUB1 N))
(COND ((ZEROP N) (RETURN M))
((GREATERP (ARG N) M) (SETQ M (ARG N))))
(GO L)))
(MAX 1 1.2 4 3 -50) = 4
(SETARG N V)
SETARG sets the value of the Nth argument to V and returns V.
6.4 MACROs
A MACRO is an identifier which has a LAMBDA expression of one
dummy variable on its property list with property name MACRO. MACROs
are evaluated by binding the list containing the macro name and the
actual argument list to the dummy variable. The body in the LAMBDA
expression is evaluated and should result in another "expanded" form.
In the interpreter, the expanded form is evaluated. In the compiler,
the expanded form is compiled. DM( see 11.1) is useful for defining
MACROs.
Examples:
1) We could define CONS of an arbitrary number of arguments by:
(DM CONSCONS (L)
(COND ((NULL (CDDR L)) (CADR L))
(T (LIST (QUOTE CONS)
(CADR L)
(CONS (QUOTE CONSCONS) (CDDR L))))))
(CONSCONS A B C) would call CONSCONS with L = (CONSCONS A B
C). CONSCONS then forms the list (CONS A(CONSCONS B C)). Evaluating
this will again call CONSCONS with L = (CONSCONS C). CONSCONS will
finally return C.
The effect of (CONSCONS A B C) is then (CONS A (CONS B C)).
2) We could define a function EXPAND which is more generally useful
for MACRO expansion:
(DE EXPAND (L FN)
(COND ((NULL (CDR L)) (CAR L))
(T (LIST FN (CAR L) (EXPAND (CDR L) FN))))))
SAILON 28.7 CHAPTER 6 6-4
Then we could define CONSCONS:
(DM CONSCONS (L) (EXPAND (CDR L) (QUOTE CONS)))
It should be noted that MACROs are more general than FEXPRs
and LEXPRs. In fact the previous definitions can be replaced by the
following MACROs:
(DM LISTQ (L) (LIST (QUOTE QUOTE) (CDR L))))
(DM MAX (L) (EXPAND (CDR L) (QUOTE *MAX)))
(MAX A B C D) would expand to:
(*MAX A (*MAX B (*MAX C D)))
3) (*EXPAND L FN)
(*EXPAND1 L FN)
*EXPAND and *EXPAND1 are MACRO expanding functions used by PLUS,
TIMES, etc. They are equivalent to:
(DE *EXPAND (L FN) (*EXPAND1 (REVERSE (CDR L)) FN))
(DE *EXPAND1 (L FN)
(COND ((NULL (CDR L)) (CAR L))
(T (LIST FN (*EXPAND1 (CDR L) FN) (CAR L)))))
Example:
With PLUS defined as
(DM PLUS (L) (*EXPAND L(QUOTE *PLUS)))
(PLUS A B C D) expands to:
(*PLUS (*PLUS (*PLUS A B) C) D)
SAILON 28.7 CHAPTER 7 7-1
CHAPTER 7
EVALUATION OF S-EXPRESSIONS
This chapter describes the heart of the LISP interpreter, the
mechanism for evaluating S-expressions.
! (*EVAL E)
(EVAL E)
*EVAL and EVAL (see 7.2) evaluate the value of the
S-expression E.
Examples:
(EVAL (LIST (QUOTE ADD1) 3)) = 4
The top level of LISP is:
(PROG NIL
L (PRINT (EVAL (READ))) (TERPRI) (GO L))
! (APPLY FN ARGS)
APPLY evaluates and binds each S-expression in ARGS to the
corresponding arguments of the function FN, and returns the value of
FN. See 7.2.
Example:
(APPLY (FUNCTION APPEND) (QUOTE ((A B) (C D)))) = (A B C D)
! (QUOTE "E")
QUOTE returns the S-expression E without evaluating it.
(FUNCTION "FN")
FUNCTION is the same as QUOTE in the interpreter. In the
compiler, FUNCTION causes the S-expression FN to be compiled, but
QUOTE generates an S-expression constant. See *FUNCTION in 7.2 for
the special FUNARG feature.
The following function definitions lack some details but
explain the essence of EVAL and APPLY. The A-LIST feature of these
functions is not shown, but will be explained in 7.2.
(DE EVAL (X)
(PROG (Y)
(RETURN
(COND ((NUMBERP X) X)
((ATOM X) (COND ((SETQ Y (GET X (QUOTE VALUE)))
(CDR Y))
(T (ERR (QUOTE (UNBOUND VARIABLE)))))
SAILON 28.7 CHAPTER 7 7-2
((ATOM (CAR X))
(COND ((SETQ Y (GETL (CAR X) (QUOTE EXPR FEXPR MACRO))))
(COND ((EQ (CAR Y) (QUOTE EXPR))
(APPLY (CADR Y)
(MAPCAR (FUNCTION EVAL) (CDR X))))
((EQ (CAR Y) (QUOTE FEXPR)
(APPLY (CADR Y) (LIST (CDR X))))
(T (EVAL (APPLY (CADR Y) (LIST X))))))
((SETQ Y (GET (CAR X) (QUOTE VALUE)))
(EVAL (CONS (CDR Y) (CDR X))))
(T (ERR (QUOTE (UNDEFINED FUNCTION))))))
(T (APPLY (CAR X) (MAPCAR (FUNCTION EVAL) (CDR X))))))))
(DE APPLY (FN ARGS)
(COND ((ATOM FN)
(COND ((GET FN (QUOTE EXPR))
(APPLY (GET FN (QUOTE EXPR)) ARGS))
(T (APPLY (EVAL FN) ARGS))))
((EQ (CAR FN) (QUOTE LAMBDA))
(PROG (Z)
(BIND (CADR FN) ARGS)
(SETQ Z (EVAL (CADDR FN)))
(UNBIND (CADR FN))
(RETURN Z)))
(T (APPLY (EVAL FN) ARGS))))
The functions BIND and UNBIND implement variable bindings as
described in the next section.
* 7.1 Variable Bindings
This section attempts to explain the different types of
variable bindings and the difference between interpreter and compiler
bindings.
* 7.1.1 Bound and Free Occurrences
An occurrence of a variable is a "bound occurrence" if the
variable is a variable in any LAMBDA or PROG containing the
occurrence so long as the occurrence is not contained in a FUNCTIONAL
argument which is contained in the defining LAMBDA or PROG. The
defining LAMBDA or PROG is the innermost LAMBDA or PROG which
contains the variable in its parameter list.
Examples:
(LAMBDA (X) (TIMES X Y))
X has a bound occurrence.
Y has a free occurrence.
(LAMBDA (Y Z) (MAPCAR (FUNCTION (LAMBDA(X) (CONS X Y)))Z)
X and Z have only bound occurrences.
Y is bound by the outer LAMBDA and free in the inner.
SAILON 28.7 CHAPTER 7 7-3
* 7.1.2 Scope of Bindings
A variable bound in a LAMBDA or PROG is defined during the
dynamic execution of the LAMBDA or PROG. Free occurrences of
variables are defined if and only if either the variable is globally
defined or the variable is bound in any LAMBDA or PROG which
dynamically contains the free occurrence. A variable is globally
defined if and only if it has a value at the top level of LISP.
Variables can be globally defined by SETQ at the top level.
* 7.1.3 Special Variables
In compiled functions, any variable which is bound in a
LAMBDA or PROG and has a free occurrence elsewhere must be declared
SPECIAL (APPENDIX E).
Example:
(LAMBDA (A B)
(MAPCAR (FUNCTION (LAMBDA (X) (CONS A X))) B))
The variable A which has a free occurrence must be declared
SPECIAL if the outer LAMBDA expression is to be compiled.
* 7.1.4 Binding Mechanisms
All variables in interpreted functions, and SPECIAL variables
in compiled functions store their values in SPECIAL (or VALUE) cells.
These variables are bound at the entry to a LAMBDA or PROG by saving
their previous values on the SPECIAL pushdown list and storing their
new values in the SPECIAL cells. All references to these variables
are directly to their SPECIAL cells. When the LAMBDA or PROG is
exited, the old values are restored from the SPECIAL pushdown list.
In compiled functions, all variables not declared SPECIAL are
stored on the REGULAR pushdown list, and the SPECIAL cells (if they
exist) are not referenced.
# 7.2 The A-LIST and FUNARG Features
The A-LIST which is used in some LISP systems to implement
recursive variable bindings does not exist here, but its effects are
simulated through a special A-LIST feature. The functions EVAL and
APPLY allow an extra last argument to be passed which is either a
list of paired identifiers and values (like an A-LIST) or a "binding
context pointer".
In the case of an A-LIST second argument, EVAL and APPLY will
bind the special cells of the variables in the A-LIST to their
specified values, saving their previous bindings on the special
pushdown list. When EVAL and APPLY return, the variable bindings are
restored to their previous values.
SAILON 28.7 CHAPTER 7 7-4
A "binding context pointer" (BCP) is a pointer into the
SPECIAL PUSHDOWN LIST designating a level in recursive variable
binding. When EVAL and APPLY receive a BCP as their second argument,
all SPECIAL (VALUE) CELLS are restored to the values they had at the
time the BCP was generated. This then causes EVAL and APPLY to
reference these variables in the binding context which existed at the
time of BCP generation. This feature primarily is useful to prevent
variable name conflicts when using EVAL, APPLY, and functional
arguments. As with the A-LIST, when EVAL and APPLY exit, the
previous bindings are restored.
There are two ways to generate a BCP:
If an FEXPR is defined with two arguments, then the second
argument will be bound to the SPECIAL PUSHDOWN LIST level at the time
the FEXPR is called.
The second way to generate a BCP is with *FUNCTION.
(*FUNCTION "FN")
*FUNCTION returns a list of the following form:
(FUNARG FN * <BCP>)
where BCP is the SPECIAL PUSHDOWN LIST level at the time *FUNCTION is
called. Whenever such a functional form is used in functional
context, all SPECIAL bindings are restored to the values they had at
the time *FUNCTION was evaluated. When the functional argument has
been APPLYed, the previous bindings are restored as with the A-LIST.
The use of FUNARGS is discussed further by Robert Saunders[3].
Example using the BCP feature:
(DF EXCHANGE (L SPECPDL)
(PROG(Z) (SETQ Z(EVAL (CAR L) SPECPDL))
(APPLY (FUNCTION SET)
(LIST (CAR L) (EVAL (CADR L) SPECPDL)
SPECPDL)
(APPLY (FUNCTION SET)
(LIST (CADR L) Z
SPECPDL)))
In this example, the use of the extra argument SPECPDL has only one
effect: to avoid conflicts between internal and external variables
with names L and SPECPDL.
(EXCHANGE L M) will cause the values of L and M to be
exchanged. The variable L in EXCHANGE is not referenced by the calls
on SET.
SAILON 28.7 CHAPTER 8 8-1
CHAPTER 8
CONDITIONAL EXPRESSIONS
A conditional expression has the following form:
! (COND (e↓1,1 e↓1,2 ... e↓1,n↓1)
(e↓2,1 e↓2,2 ... e↓2,n↓2)
...
(e↓m,1 e↓m,2 ... e↓m,n↓m))
where the e↓i,j's are any S-expressions.
The e↓i,1's are considered to be predicates, i.e., evaluate
to a truth value. The e↓i,1's are evaluated starting with e↓1,1 ,
e↓2,1 , etc., until the first e↓k,1 is found whose value is not NIL.
Then the corresponding e↓k,2 e↓k,3 ...e↓k,n↓k are evaluated
respectively and the value of e↓k,n↓k is returned as the value of
COND. It is permissible for n↓k =1, in which case the value of e↓k,1
is the value of COND. If all e↓i,1 evaluate to NIL, then NIL is the
value of COND.
Examples:
(DE NOT (X) (COND (X NIL) (T)))
(DE AND (X Y) (COND (X (COND (Y T)))))
(DE OR (X Y) (COND (X T) (Y T)))
(DE IMPLIES (X Y) (COND (X (COND (Y T))) (T)))
SAILON 28.7 CHAPTER 9 9-1
CHAPTER 9
PREDICATES
Predicates test S-expressions for particular values, forms,
or ranges of values. All predicates described in this chapter return
either NIL or T corresponding to the truth values false and true,
unless otherwise noted. Some predicates cause error messages or
undefined results when applied to S-expressions of the wrong type,
such as (MINUSP (QUOTE FOO)).
! (ATOM X)
The value of ATOM is T if X is either an identifier or a
number; NIL otherwise.
Examples: (ATOM T) = T
(ATOM 1.23) = T
(ATOM (QUOTE (X Y Z))) = NIL
(ATOM (CDR (QUOTE (X))) = T
! (EQ X Y)
The value of EQ is T if X and Y are the same pointer, i.e.,
the same internal address. Identifiers on the OBLIST have unique
addresses and therefore EQ will be T if X and Y are the same
identifier. EQ will also return T for equivalent INUMs, since they
are represented as addresses. However, EQ will not compare equivalent
numbers of any other kind. For non-atomic S-expressions, EQ is T if X
and Y are the same pointer.
Examples: (EQ T T) = T
(EQ T NIL) = NIL
(EQ (QUOTE A) (QUOTE B)) = NIL
(EQ 1 1.0) = NIL
(EQ 1 1) = T
(EQ 1.0 1.0) = NIL
(EQUAL X Y)
The value of EQUAL is T if X and Y are identical
S-expressions. EQUAL can also test for equality of numbers of mixed
types. EQUAL is equivalent to:
(LAMBDA(X Y) (COND ((EQ X Y) T)
((AND (NUMBERP X) (NUMBERP Y))
(ZEROP (*DIF X Y)))
((OR (ATOM X)(ATOM Y)) NIL)
((EQUAL (CAR X) (CAR Y))
(EQUAL (CDR X) (CDR Y)))))
SAILON 28.7 CHAPTER 9 9-2
Examples: (EQUAL T T) = T
(EQUAL 1 1) = T
(EQUAL 1 1.0) = T
(EQUAL (QUOTE (A B)) (QUOTE (A B))) = T
(EQUAL (QUOTE (T)) T) = NIL
! 9.1 S-Expression Predicates
(NULL L) = T if and only if L is NIL.
(MEMBER L1 L2) = T if and only if L1 is EQUAL to a top level element of L2.
MEMBER is equivalent to:
(LAMBDA(L1 l2) (COND ((ATOM L2) NIL)
((EQUAL L1 (CAR L2))T)
(T(MEMBER L1 (CDR L2)))))
Examples: (MEMBER (QUOTE (C D)) (QUOTE ((A B)(C D)E))) = T
(MEMBER (QUOTE C)(QUOTE (C)))) = NIL
(MEMQ L1 L2) = T iff L1 is EQ to a top level element of L2.
MEMQ is equivalent to:
(LAMBDA(L1 L2)(COND ((ATOM L2) NIL)
((EQ L1 (CAR L2)) T)
(T(MEMQ L1 (CDR L2)))))
Examples: (MEMQ (QUOTE (C D))(QUOTE ((A B)(C D) E))) = NIL
(MEMQ (QUOTE A) (QUOTE (Q A B))) = T
! 9.2 Numerical Predicates
(NUMBERP X) = T if X is a number of any type
= Nil otherwise
(ZEROP X) = T if X is zero of any numerical type
= error if X is a non-numerical quantity
= NIL otherwise
(MINUSP X) = T if X is a negative number of any type
= error if X is a non-numerical quantity
= NIL otherwise
(*GREAT X Y) = T if X and Y are numbers of any type and X > Y.
= error if either X or Y is not a number
= NIL otherwise
(*LESS X Y) = (*GREAT Y X)
SAILON 28.7 CHAPTER 9 9-3
(GREATERP X↓1 X↓2 ...X↓n) = T if (*GREAT X↓1 X↓2) and
(*GREAT X↓2 X↓3) and
(*GREAT X↓n-1 X↓n)
= error if any X↓i is a non-numerical
quality
= NIL otherwise
(LESSP X↓1 X↓2 ... X↓n) = (GREATERP X↓n X↓n-1 ... X↓1)
Other numerical predicates may be defined as follows:
(DE FLOATP (X) (COND ((EQ X (PLUS X 0))NIL)
((EQ (CADR X) (QUOTE FLONUM)) T)
(T NIL)))
(DE FIXP (X) (NOT(FLOATP X)))
(DE ONEP (X) (ZEROP (DIFFERENCE X 1)))
(DE EVENP (X) (ZEROP (REMAINDER X 2)))
! 9.3 Boolean Predicates
The Boolean predicates perform logical operations on the
truth values NIL and T. A non-NIL value is considered equal to T.
(NOT X) = T if X is NIL
= NIL otherwise
(AND X↓1 X↓2 ...X↓n) = T if all X↓i are non-NIL
= NIL otherwise
Note: (AND) = T. AND evaluates its arguments from left to right
until either NIL is found in which case the remaining
arguments are not evaluated, or until the last argument
is evaluated.
(OR X↓1 X↓2 ... X↓n) = T if any X↓i is non-NIL
= NIL otherwise
Note: (OR) = NIL. OR evaluates its arguments from left to right
until either non-NIL is found in which case the remaining
arguments are not evaluated, or until the last argument is
evaluated.
SAILON 28.7 CHAPTER 10 10-1
CHAPTER 10
FUNCTIONS ON S-EXPRESSIONS
This chapter describes functions for building, fragmenting,
modifying, transforming, mapping, and searching S-expressions, as
well as some non-standard functions on S-expressions.
! 10.1 S-Expression Building Functions
(CONS X Y)
The value of CONS of two S-expressions is the dotted pair of
those S-expressions.
Example: (CONS (QUOTE A) (QUOTE B)) = (A.B)
Note: See Appendix D for information on functions associated with
CONSing, such as SPEAK, GCGAG, and GC.
(XCONS X Y) = (CONS Y X)
(NCONS X) = (CONS X NIL)
(LIST X↓1 ... X↓n) = (CONS X↓1 (CONS X↓2 ...(CONS X↓n NIL)...))
List evaluates all of its arguments and returns a list of
their values.
Examples: (LIST) = NIL
(LIST (QUOTE A)) = A
(LIST (QUOTE A) (QUOTE B)) = (A B)
(*APPEND X Y)
(DE *APPEND (X Y)
(COND ((NULL X) Y)
(T (CONS (CAR X) (*APPEND (CDR X) Y)))))
(APPEND X↓1 X↓2 ...X↓n) = (*APPEND X↓1 (*APPEND X↓2 ...(*APPEND X↓n NIL)...))
Example: (APPEND) = NIL
(APPEND (QUOTE (A B)) (QUOTE (C D)) (QUOTE (E))) = (A B C D E)
! 10.2 S-Expression Fragmenting Functions
(CAR L)
The CAR of a non-atomic S-expression is the first element of
that dotted pair. CAR of an atom is undefined and will usually cause
an illegal memory reference.
SAILON 28.7 CHAPTER 10 10-2
(CDR L)
The CDR of a non-atomic S-expression is the second (and last)
element of that dotted pair. The CDR of an identifier is its
property list. The CDR of an INUM causes an illegal memory
reference. The CDR of any other number is the list structure
representation of that number.
Examples: (CAR (QUOTE (A B C))) = A
(CAR (QUOTE A)) is illegal
(CDR (QUOTE (A B C))) = (B C)
(CDR (QUOTE A)) is the property list of A
(CDR (QUOTE (A))) = NIL
CAAR, CADR,..., CDDDDR
All of the composite CAR-CDR functions with up to four A's
and D's are available.
Examples: (CADR X) = (CAR (CDR X))
(CAADDR X) = (CAR (CAR (CDR (CDR X))))
(LAST L)
LAST returns the last part of a list according to the
following definition:
(DE LAST (L)
(COND ((ATOM (CDR L)) L)
(T (LAST (CDR L)))))
Examples: (LAST (QUOTE (A B C))) = (C) = (C.NIL)
(LAST (QUOTE (A B . C))) = (B.C)
* 10.3 S-Expression Modifying Functions
The following functions for manipulating S-expressions differ
from all others in that they actually modify existing list structure
rather than constructing new list structure. These functions should
be used with caution since it is easy to create structures which will
confuse or destroy the interpreter.
(RPLACA X Y)
Replaces the CAR of X by Y. The value of RPLACA is the modified
S-expression X.
Example: (RPLACA (QUOTE (A B C)) (QUOTE (C D))) = ((C D) B C)
SAILON 28.7 CHAPTER 10 10-3
Representation:
_________ _________ _________
X → | A | | → | B | | → | C |NIL|
BEFORE |___|___| |___|___| |___|___|
_________ _________
Y → | C | | → | D |NIL|
|___|___| |___|___|
_________ _________ _________
X → | A | | → | B | | → | C |NIL|
|___|___| |___|___| |___|___|
↓
_________ _________
Y → | C | | → | D |NIL|
|___|___| |___|___|
(RPLACD X Y)
RPLACD replaces the CDR of X by Y. The value of RPLACD is
the modified S-expression X.
(NCONC X↓1 X↓2 ... X↓n)
NCONC is similar in effect to APPEND, but NCONC does not copy
list structures. NCONC modifies list structures by replacing the
last element of X↓1 by a pointer to X↓2, the last element of X↓2 by a
pointer to X↓3, etc. The value of NCONC is the modified list X↓1,
which is the concatenation of X↓1. X↓2, ..., X↓n.
Examples: (NCONC) = NIL
(NCONC (QUOTE (A B)) (QUOTE (C D))) = (A B C D)
Representation:
_________ _________
X↓1 → | A | | → | B |NIL|
BEFORE |___|___| |___|___|
_________ _________
X↓2 → | C | | → | D |NIL|
|___|___| |___|___|
_________ _________
X↓1 → | A | | → | B | |
AFTER |___|___| |___|___|
|
|---------------|
__↓______ _________
X↓2 → | C | | → | D |NIL|
|___|___| |___|___|
SAILON 28.7 CHAPTER 10 10-4
10.4 S-Expression Transforming Functions
The following functions transform S-expressions from one form to
another.
(LENGTH L)
LENGTH returns the number of top-level elements of the list
L. LENGTH is equivalent to:
(DE LENGTH (L)
(COND ((ATOM L) 0)
(T (ADD1 (LENGTH (CDR L))))))
(REVERSE L)
REVERSE returns the reverse of the top level of list L.
REVERSE is equivalent to:
(DE REVERSE (L) (REVERSE1 L NIL))
(DE REVERSE 1 (L M)
(COND ((ATOM L) M)
(T (REVERSE1 (CDR L) (CONS (CAR L) M)))))
(SUBST X Y S)
SUBST substitutes S-expression X for all EQUAL occurrences of
S-expression Y in S-expression S. SUBST is equivalent to:
(DE SUBST (X Y S)
(COND ((EQUAL Y S) X)
((ATOM S) S)
(T (CONS (SUBST X Y (CAR S))
(SUBST X Y (CDR S))))))
Note: (SUBST 0 0 X) is useful for creating a copy of the list X.
Example: (SUBST 5 (QUOTE FIVE) (QUOTE (FIVE PLUS FIVE IS TEN)))
= (5 PLUS 5 IS TEN)
10.5 S-Expression Mapping Functions
The following functions perform mappings of lists according
to the functional arguments supplied.
(MAP FN L)
MAP applies the function FN of one argument to list L and to
successive CDRs of L until L is reduced to NIL. The value of MAP is
NIL. MAP is equivalent to:
SAILON 28.7 CHAPTER 10 10-5
(DE MAP (FN L)
(PROG NIL
L1 (COND ((NULL L)(RETURN NIL)))
(FN L)
(SETQ L (CDR L))
(GO L1)))
Example: (MAP (FUNCTION PRINT) (QUOTE (X Y Z))) =
PRINT: (X Y Z)
PRINT: (Y Z)
PRINT: (Z)
PRINT: NIL
(MAPC FN L)
MAPC is identical to MAP except that MAPC applies function FN
to the CAR of the remaining list at each step. MAPC is equivalent to:
(DE MAPC (FN L)
(PROG NIL
L1 (COND ((NULL L)(RETURN NIL)))
(FN (CAR L))
(SETQ L (CDR L))
(GO L1)))
Example: (MAPC (FUNCTION PRINT) (QUOTE (X Y Z))) =
PRINT: X
PRINT: Y
PRINT: Z
PRINT: NIL
(MAPLIST FN L)
MAPLIST applies the function FN of one argument to list L and
to successive CDRs of L until L is reduced to NIL. The value of
MAPLIST is the list of values returned by FN. MAPLIST is equivalent
to:
(DE MAPLIST (FN L)
(COND ((NULL L) NIL)
(T (CONS (FN L) (MAPLIST FN (CDR L))))))
Examples: (MAPLIST (FUNCTION CAR) (QUOTE (A B C D))) = (A B C D)
(MAPLIST (FUNCTION REVERSE) (QUOTE (A B C D))) =
((D C B A) (D C B) (D C) (D))
(MAPCAR FN L)
SAILON 28.7 CHAPTER 10 10-6
MAPCAR is identical to MAPLIST except that MAPCAR applies FN
to the CAR of the remaining list at each step. MAPCAR is equivalent
to:
(DE MAPCAR (FN L)
(COND ((NULL L) NIL)
(T (CONS (FN (CAR L)) (MAPCAR FN (CDR L))))))
Examples: (MAPCAR (FUNCTION NCONS) (QUOTE (A B C D))) = ((A) (B) (C) (D))
(MAPCAR (FUNCTION ATOM) (QUOTE ((X) Y (Z)))) = (NIL T NIL)
10.6 S-Expression Searching Functions
(ASSOC X L)
ASSOC searches the list of dotted pairs L for a pair whose
CAR is EQ to X. If such a pair is found it is returned as the value
of ASSOC, otherwise NIL is returned. ASSOC is equivalent to:
(DE ASSOC (X L)
(COND ((NULL L) NIL)
((EQ X (CAAR L)) (CAR L))
(T (ASSOC X (CDR L)))))
Example: (ASSOC 1 (QUOTE ((1.ONE) (2.TWO)))) = (1.ONE)
(SASSOC X L FN)
SASSOC searches the list of dotted pairs L for a pair whose
CAR is EQ to X. If such a pair is found it is returned as the value
of ASSOC, otherwise the value of FN, a function of no arguments, is
returned.
(DE SASSOC (X L FN)
(COND ((NULL L) (FN))
((EQ X (CAAR L)) (CAR L))
(T (SASSOC X (CDR L) FN))))
Example: (SASSOC 0 (QUOTE ((1.ONE) (2.TWO)))
(FUNCTION (LAMBDA NIL (QUOTE LOSE)))) = LOSE
10.7 Character List Transforming Functions
(EXPLODE L)
EXPLODE transforms an S-expression into a list of single
character identifiers identical to the sequence of characters which
would be produced by PRINC.
Example: (EXPLODEC (QUOTE (DX_/-_DY)))
= (/(D X / _ / - / _ D Y/))
SAILON 28.7 CHAPTER 10 10-7
(FLATSIZE L) = (LENGTH (EXPLODE L))
(MAKNUM L)
MAKNUM transforms a list of single character identifiers
(actually takes the first character of each identifier) into an
S-expression identical to that which would be produced by READing
those characters. MAKNAM however does not INTERN any of the
identifiers in the S-expression it produces.
Examples: (MAKNUM (QUOTE (A P P L E))) = APPLE
(MAKNAM (QUOTE (//_/)))) = /)
(READLIST L)
READLIST is identical to MAKNAM except that READLIST INTERNs
all identifiers in the S-expression it produces. READLIST is the
logical inverse of EXPLODE, i.e.,
(READLIST (EXPLODE L)) = L
(EXPLODE (READLIST L)) = L
SAILON 28.7 CHAPTER 11 11-1
CHAPTER 11
FUNCTIONS ON IDENTIFIERS
There are three basic types of functions on identifiers:
those which manipulate their property lists, those which create new
identifiers, and those which control their membership in the OBLIST.
NOTE: All functions described in this chapter which expect an
identifier as one (or more) of its arguments will give either
erroneous results, or an error condition if any S-expression other
than an identifier is supplied.
11.1 Property List Functions
(GET I P)
GET is a function which searches the property list of the
identifier I looking for the property name which is EQ to P. If such
a property name is found, the value associated with it is returned as
the value of GET, otherwise NIL is returned. Note that confusion
exists if the property is found, but its value is NIL. GET is
equivalent to:
(DE GET (I P) (COND ((NULL (CDR I)) NIL)
((EQ (CADR I) P) (CADDR I))
(T (GET (CDDR I) P))))
(GETL I L)
GETL is another function which searches property lists. GETL
searches the property list of the identifier I looking for the first
property which is a member (MEMQ) of the list L. GETL returns the
remaining property list, including the property name if any such
property was found, NIL otherwise. GETL is equivalent to:
(DE GETL (I L) (COND ((NULL (CDR I)) NIL)
((MEMQ (CADR I) L) (CDR I))
(T (GETL (CDDR I) L))))
(PUTPROP I V P)
PUTPROP is a function which enters the property name P with
property value V into the property list of identifier I. If the
property name P is already in the property list, the old property
value is replaced by the new one; otherwise the new property name P
and its value V are placed on the beginning of the property list.
PUTPROP returns V.
(REMPROP I P)
SAILON 28.7 CHAPTER 11 11-2
REMPROP removes the property P from the property list of
identifier I. REMPROP returns T if there was such a property, NIL
otherwise.
SET and SETQ are used to change the values of variables which
are bound by either LAMBDA or PROG, or variables which are bound
globally. (See 7.1).
* (SET E V)
SET changes the value of the identifier specified by the
expression E to V and returns to V. Both arguments are evaluated.
Note: In compiled functions, SET can be used only on globally bound
and special variables.
! (SETQ "ID" V)
SETQ changes the value of ID to V and returns V. SETQ
evaluates V, but does not evaluate ID.
(DEFPROP "I" "V" "P") = (PROG2 (PUTPROP (QUOTE I) (QUOTE V) (QUOTE
P))(QUOTE I))
DEFPROP is the same as PUTPROP except that it does not
evaluate its arguments, and DEFPROP returns I.
Example: (DEFPROP POSP (LAMBDA (X) (GREATERP X 0)) EXPR)
(DE "ID" "ARGS" "BODY")
DE places the form (LAMBDA ARGS BODY) on the property list of
ID under property EXPR. If ID previously had any of the properties
EXPR, FEXPR, SUBR, FSUBR, LSUBR, or MACRO, then DE will return the
list (ID REDEFINED). Otherwise, DE returns ID.
(DF "ID" "ARGS" "BODY")
Same as DE except defines a function with FEXPR property.
(DM "ID" "ARGS" "BODY")
Same as DE except defines a MACRO.
11.2 OBLIST Functions
(INTERN I)
INTERN puts the identifier I in the appropriate bucket of
OBLIST. If the identifier is aready a member of the OBLIST, then
INTERN returns a pointer to the identifier already there. Otherwise,
INTERN returns I.
SAILON 28.7 CHAPTER 11 11-3
Note: INTERN is only necessary when an identifier which was created
by
GENSYM, MAKNAM, or ASCII needs to be uniquely stored.
(REMOB "X↓1" "X↓2 ... "X↓n")
REMOB removes all of the identifiers X↓1, X↓2, ... , X↓n from
the OBLIST and returns NIL. None of the X↓i's are evaluated.
Example: (REMOB FOO BAZ)
11.3 Identifier Creating Functions
The following functions create new identifiers but do not
INTERN them onto the OBLIST.
(GENSYM)
GENSYM increments the generated symbol counter and returns a
new identifier specified by the counter. The GENSYM counter is
initialized to the identifier G0000. Successive executions of
(GENSYM) will return.
G0001, G0002, G0003, ...
(CSYM "I")
CSYM initializes generated symbol counter to the identifier
I, and returns I. CSYM does not evaluate its argument.
Example: (CSYM ARY00) = ARY00
(GENSYM) = ARY01
(GENSYM) = ARY02
etc.
(ASCII N)
ASCII creates a single character identifier whose ASCII print
name equals N.
Example: (AsCII 101) is an identifier with print name "A".
SAILON 28.7 CHAPTER 12 12-1
CHAPTER 12
FUNCTIONS ON NUMBERS
There are two types of functions which operate on numbers to
create new numbers: arithmetic and logical.
! 12.1 Arithmetic Functions
Unless otherwise noted, the following arithmetic functions
are defined for both integer, real and mixed combinations of
arguments, and evaluate all their arguments. The result is real if
any argument is real, and integer if all arguments are integer. Most
arithmetic functions may cause overflow which produces an error
message.
(MINUS X) = -X
(*PLUS X Y) = X + Y
(PLUS X1 X2 ... Xn) = X1 + X2 + ... + Xn
(*DIF X Y) = X - Y
(DIFFERENCE X1 X2...Xn) = X1 - X2 - ... -Xn
(*TIMES X Y) = X * Y
(TIMES X1 X2 ... Xn) = X1 * X2 * ... * Xn
(*QUO X Y) = X / Y
(QUOTIENT X1 X2 ...Xn) = X1 / X2 / ... / Xn
For integer arguments, *QUO and QUOTIENT give the integer
part of the real quotient of the arguments.
Examples: (*QUO 5 2) = 2
(*QUO -5 2) = -2
(REMAINDER X Y) ... X - (X / Y) * Y
Note: Remainder is not defined for real arguments.
(DIVIDE X Y) = (CONS (QUOTIENT X Y) (REMAINDER X Y))
(GCD X Y) GCD returns the greatest common divisor of the integers X
and Y.
(ADD1 X) = X + 1 (SUB1 X) = X - 1
(ABS X) = | X |
SAILON 28.7 CHAPTER 12 12-2
(FIX X) returns the largest integer not greater than X.
Examples: (FIX 1) = 1
(FIX 1.1) = 1
(FIX -1.1) = -2 not -1
Other arithmetic functions not defined in the LISP interpreter
can be defined as follows:
(FLOAT X) = (*PLUS X 0.0)
(RECIP X) = (QUOTIENT 1 X)
(SIGN X) = (COND ((ZEROP X) 0)
((MINUSP x) -1)
(T 1))
(ROUND X) = (TIMES (SIGN X) (FIX (PLUS (ABS X) 0.5)))
Examples: (ROUND .5) = 1
(ROUND .49) = 0
(ROUND -.49) = 0
(ROUND -35.1) = -35
(MIN X Y) = (COND ((LESSP X Y) X) (Y))
(MAX X Y) = (COND ((LESSP X Y) Y) (X))
Examples: (MINUS 1) = -1
(MINUS -1.2) = 1.2
(PLUS 1 2 3.1 = 6.1
(PLUS 6 3 -2) = 7
(DIFFERENCE 6 3 1) = 2
(TIMES -2 2.0) = -4.0
(QUOTIENT 5 2) = 2
(QUOTIENT 5.0 2) = 2.5
(QUOTIENT -5 2) = 2
(REMAINDER 5 2) = 1
(REMAINDER -5 2) = -1
(REMAINDER 5.0 2) = undefined
(ABS -32.5) = 32.5
(FIX 32.5) = 32.
(FIX -32.5) = -33.
12.2 Logical Functions
The following functions are intended to operate on INUM and
FIXNUM arguments, but their results are not defined for BIGNUM or
FLONUM (real) arguments.
(BOOLE N X1 X2 ... Xn)
SAILON 28.7 CHAPTER 12 12-3
BOOLE causes a 36 bit Boolean operation to be performed on
its arguments. The value of N specifies which of 16 Boolean
operations to perform.
For n = 2, each bit↓i in ( BOOLE N A B) is defined:
N result N result
_ _
0 0 10 A↓i ∧ B↓i
1 A↓i∧B↓i 11 A↓i ≡ B↓i
_ _
2 A↓i∧B↓i 12 A↓i
_
3 B↓i 13 A↓i∨B↓i
_ _
4 A↓i∧B↓i 14 B↓i
_
5 A↓i 15 A↓i∨B↓i
_
6 A↓i ≠ B↓i 16 A↓i∨B↓i
7 A↓i∨B↓i 17 1
For n > 2, BOOLE is defined:
(BOOLE N ... (BOOLE N (BOOLE N X1 X2) X3) ... Xn)
(LSH X N)
LSH performs a logical left shift of N places on X. If n is
negative, X will be shifted right. In both cases, vacated bits are
filled with zeros.
Examples with IBASE = 8
(BOOLE 1 76 133) = 32
(BOOLE 1 76 133 70) = 30
(BOOLE 12 13 0) = 777777777764
(BOOLE 7 7 12) = 17
(LSH 15 2) = 64
(LSH 15 -2) = 3
(LSH -1 -2) = 177777777777
SAILON 28.7 CHAPTER 13 13-1
CHAPTER 13
PROGRAMS
The "program feature" allows one to write ALGOL-like
sequences of statements with program variables and labels.
(PROG "VARLIST" "BODY")
PROG is a function which takes as arguments VARLIST, a list
of program variables which are initialized to NIL when the PROG is
entered (see 7.1), and a BODY which is a list of labels (which are
identifiers) and statements which are non-atomic S-expressions. PROG
evaluates its statements in sequence until either a RETURN or GO is
evaluated, or the list of statements is exhausted, in which the value
of PROG is NIL.
(RETURN X)
RETURN causes the PROG containing it to be exited with the
value X.
(GO "ID")
GO causes the sequence of control within a PROG to be
transferred to the next statement following the label ID. In
interpreted PROGs, if ID is non-atomic, it is repeatedly evaluated
until an atomic value is found. However, in compiled PROGs, ID is
evaluated only once. GO cannot transfer into or out of a PROG.
Note: Both RETURN and GO should only occur either at the top level
of a PROG, or in compositions of COND, AND, OR, and NOT which are at
the top level of a PROG.
Example: The function LENGTH may be defined as follows:
(DE LENGTH (L)
(PROG (N)
(SETQ N 0)
L1 (COND ((ATOM L) (RETURN N)))
(SETQ N (ADD1 N))
(SETQ L (CDR L))
(GO L1)))
(PROG2 X↓1 X↓2 ... X↓n) , n≤5.
PROG2 evaluates all expressions X↓1 X↓2 ... X↓n, and returns
the value of X↓2.
SAILON 28.7 CHAPTER 14 14-1
CHAPTER 14
INPUT/OUTPUT
14.1 File Names
Syntax: <filename - list> ::= <device-name>
::= <filename-list><device-name>
::= <filename-list><file - name>
<device - name> ::= <identifier> :
::= (<atom><atom>)
<filename> ::= <identifier>
::= (<identifier> . <identifier>)
Semantics:
A device-name is either an identifier ending with colon (:)
which is the name of some input or output device, or a list
containing a project-programmer number which implicitly specifies the
disk.
A filename is either an identifier which specifies a filename
with a blank extension, or a dotted pair of filename and extension.
In both cases the filename applies to the most recently (to the left)
specified device-name.
14.2 Channel Names
Channel names can optionally be assigned to files selected by
the functions INPUT and OUTPUT. A channel name is any identifier
which is not followed by a colon. If no channel name is specified to
INPUT or OUTPUT then the channel name T is assumed. The channel name
NIL specifies the teletype in the functions INC and OUTC. Up to 14
channels may be active at any time.
14.3 Input
14.3.1 Selection and Control
(INPUT "CHANNEL" . "FILENAME-LIST")
INPUT releases any file previously initialized on the
channel, and initializes for input the first file specified by the
filename-list. INPUT returns the channel if one was specified, T
otherwise. INPUT does not evaluate its arguments.
(INC CHANNEL ACTION)
INC selects the specified channel for input. The channel NIL
selects the teletype. If ACTION = NIL then the previously selected
input file is not released, but only deselected. If ACTION = T then
that file is released, making the previously selected channel
SAILON 28.7 CHAPTER 14 14-2
available. At the top level, ACTION need not be specified.
The input functions in 14.3.3 receive input from the selected
input channel. When a file on the selected channel is exhausted,
then the next file in the filename-list for the channel is
initialized and input, until the filename-list is exhausted. Then
the teletype is automatically selected for input and (ERR (QUOTE
$EOF$)) is called. The use of ERRSET around any functions which
accept input therefore makes it possible to detect end of file. If
no ERRSET is used, control returns to the top level of LISP. INC
evaluates its arguments, and returns the previously selected channel
name.
In order to READ from multiple input sources, separate
channels should be initialized by INPUT, and INC can then select the
appropriate channel to READ from.
Example: The following show a fairly typical sort of manipulation of two
files at once.
(LAMBDA (FILE)
(PROG (CHAN1 CHAN2 EXPR1 EXPR2)
(SETQ CHAN1 (INPUT DSK: FOO))) ;initialize FOO with channel name T
(SETQ CHAN2 (EVAL (LIST @INPUT (GENSYM) @DSK: FILE)))
;this file is given a GENSYM channel name to prevent
with any existing channels
LOOP (INC CHAN1 NIL) ;select first channel
(SETQ EXPR1 (READ)) ;read an expression from FOO
(COND ((EQ EXPR1 (QUOTE *EOF*)) (GO EXIT1))) ;end of first file?
(SETQ EXPR1 (CAR EXPR1)) ;undo effect of ERRSET
(INC CHAN2 NIL) ;open second channel
(SETQ EXPR2 (ERRSET READ)) ;read an expression
(COND ((EQ EXPR2 (QUOTE *EOF*)) (GO EXIT2)) ;end of this file?
((ATOM EXPR2) (GO ERROR))) ;read error?
(SETQ EXPR2 (CAR EXPR2)) ;undo effect of errset
..........................
process in EXPR1 and EXPR2
..........................
(GO LOOP)
ERROR ;error routine
EXIT1 ;exit when first file ends first
EXIT2 ;exit when sencond file ends first
etc.
(DSKIN . "FILENAME-LIST")
In loading a file into a LISP program, it is not normally
necessary to make use of the full generality available in INC and
INPUT. The function DSKIN is supplied for this purpose. It has the
same effect as doing INC and INPUT on its arguments, except that no
channel name is admissible, and no device name is required. The
SAILON 28.7 CHAPTER 14 14-3
channel name will always be T, and `DSK' will be supplied as a device
name, if none is given.
Example:
(DSKIN FOO DTA3: BAR (1,JMC) (SIMU.MAN))
will READ the files FOO from DSK:, BAR from DTA3: and
SIMU.MAN from the disk area [1,JMC].
When reading an input file, it is sometimes desirable to know
the page and line being read from. PGLINE returns the dotted pair
(page number . line number) for the selected input file. The page
number is applicable only to STOPGAP files. If the file has no line
numbers, PGLINE will always return (1 . 0).
14.3.2 Teletype Input Control
When input is from the teletype, READ is terminated by either
an entire S-expression or by an incomplete S-expression followed by
altmode. Altmode has the effect of typing a space followed by the
appropriate number of right parens to complete the S-expression.
This feature is particularly useful when an unknown number of right
parens are needed or when in (DDTIN NIL) mode.
* (DDTIN X)
DDTIN is a function which selects teletype input mode. With
(DDTIN NIL), and typing to READ, READCH, or TYI, a rubout will delete
the last character typed, and control U (↑U) will delete the entire
last line typed. Input is not seen by LISP until either altmode or
carriage return is typed.
With (DDTIN T) and typing to READ, a rubout will delete the
entire S-expression being read and start reading again.
Note: (DDTIN T) is not recommended when the time-sharing system is
swapping, since the program is reactivated (and hence swapped
into core) after every character typed.
14.3.3 Input Transfer
! (READ)
READ causes the next S-expression to be read from the
selected input device, and returns the internal representation of the
S-expression. READ uses INTERN to guarantee that references to the
same identifier are EQ.
READ will accept any S-expression which conforms to the
following syntax:
SAILON 28.7 CHAPTER 14 14-4
Syntax:
<readable S-expr> ::= <atom>
::= @<readable S-expr>
::= (<readable S-exprlist>
{.<readableS-expr>})
::= [<unbalanced S-expression list>]
::= ( ) = NIL
<readable S-expr list> ::= <readable S-expr>
::= <readable S-expr><readable S-
expression list>
Semantics:
The delimiter "@" designates that the following readable
S-expression is to be quoted.
Examples: @A means (QUOTE A)
@(@A B) means (QUOTE ((QUOTE A) B))
@@A means (QUOTE (QUOTE A)))
The delimiters "[" and "]" operate as "super-parentheses". A
right bracket "]" will close all open left parentheses ")" up to the
matching left bracket "[". If there is no matching left bracket, it
will close the entire S-expression as does altmode. No syntax is
given for unbalanced-S-expression-list, but it is intended to mean an
S-expression-list which is lacking one or more right parentheses.
Example: (COND [(ATOM X) (REVERSE(CDR Y][T(APPEND Y Z])
(COND ((ATOM X) (REVERSE(CDR Y)))(T(APPEND Y Z)))
(READCH)
READCH causes the next character to be read from the selected
input device and returns the corresponding single character
identifier. READCH also uses INTERN.
(TYI)
TYI causes the next character to be read from the selected
input device and returns the ASCII code for that character.
A function TEREAD which ignores all characters until a
line-feed is seen can be defined:
(DE TEREAD NIL
(PROG NIL
L (COND ((EQ (TYI) 12) (RETURN NIL)))
(GO L)))
SAILON 28.7 CHAPTER 14 14-5
14.4 Output
14.4.1 Selection and Control
(OUTPUT "CHANNEL" . "FILENAME-LIST")
OUTPUT initializes for output on the specified channel the
single file specified by the filename-list. OUTPUT does not evaluate
its arguments, and returns the channel name if specified, T
otherwise.
(OUTC CHANNEL ACTION)
OUTC selects the specified channel for output. The channel
NIL selects the teletype. The output functions in 14.4.3 transfer
output to the selected output channel.
If ACTION = NIL, then the previously selected output file is
not closed, but only deselected. If ACTION = T then that file is
closed, i.e., an end of file is written. OUTC evaluates its
arguments and returns the previously selected channel name. At the
top level, ACTION need not be specified.
Examples: (At the top level)
(OUTC (OUTPUT LPT:) T)
(OUTC NIL T)
(OUTPUT FOO DSK: BAZ)
(OUTC (QUOTE FOO) NIL)
(LINELENGTH N)
LINELENGTH is used to examine or change the maximum output
linelength on the selected output channel. If N = NIL then the
current linelength is returned unchanged, otherwise the linelength is
changed to the value of N which is returned and must be an integer.
(CHRCT)
CHRCT returns the number of character positions remaining on
the output line of the selected output channel.
When characters are output, if CHRCT is made negative, an
ASCII 176 followed by a carriage-return and a line-feed are output.
These characters are completely ignored on input. (See Chapter 3).
14.4.2 Output Transfer
! (PRIN1 S)
PRIN1 causes the S-expression S to be printed on the selected
output device with no preceding or following spaces. PRIN1 also
inserts slashes ("/") before any characters in identifiers which
SAILON 28.7 CHAPTER 14 14-6
would be syntactically incorrect otherwise (see Chapter 3). Double
quotes around strings are printed.
(PRINC S)
PRINC is the same as PRIN1 except that no slashes are
inserted and double quotes around strings are not printed.
(TERPRI X)
TERPRI prints a carriage-return and line-feed and returns the
value of X. X may be omitted if the value of TERPRI is not used.
Example: (PRINC(TERPRI X))
is the same as
(PROG2 (TERPRI)(PRINC X))
! (PRINT S)
= (PROG2 (TERPRI)
(PRIN1 S)
(PRINC (QUOTE/_)))
(TYO N)
TYO prints the character whose ASCII value is N, and returns
N.
SAILON 28.7 CHAPTER 15 15-1
CHAPTER 15
ARRAYS
(ARRAY "ID" TYPE B↓1 B↓2 ... B↓n) n≤ 5.
ARRAY is a function which declares an array with name ID, and
places an array referencing function on the property list of ID. TYPE
determines the type of an array as follows:
TYPE INITIAL VALUE ARRAY ELEMENT
T NIL LISP S-expressions stored as
pointers; 2 per word.
NIL 0.0 REAL numbers stored one per word in
PDP-6/10 floating point representation.
36. 0 36 bit 2/s complement integers stored
1 per word.
0<n<36. 0 n bit positive integers packed
[36./n] per word.
B↓1 B↓2 ... B↓n are array subscript bounds which should evaluate to
either positive integers S↓i, or to dotted pairs of integers (L↓i .
U↓i) where L↓i≤U↓i, which specify lower and upper subscript bounds as
follows:
B↓i LOWER BOUND UPPER BOUND LENGTH
S↓i 0 S↓i - 1 S↓i
(L↓i . U↓i) L↓i U↓i U↓i-L↓i + 1
The elements of an array are referenced by:
(<array name> i↓1 i↓2 ... i↓n) where L↓j ≤ i↓j < U↓j.
The ARRAY subscripts i↓j must be integers. References to memory
locations outside of the area reserved for the array are prohibited
and will cause an illegal memory reference message. Array elements
are stored in BINARY PROGRAM SPACE.
Examples:
1) To declare a 1 dimensional array CHARS of 7 bit characters and
with subscripts 1 to 50:
(ARRAY CHARS 7 (QUOTE (1 . 50)))
The first element of CHARS is referenced:
SAILON 28.7 CHAPTER 15 15-2
(CHARS 1)
2) To declare a 2-dimensional array A of REAL numbers and with
subscripts 0 ≤ i < N, 0 ≤ j < M:
(ARRAY A NIL N M)
3) To declare a 1-dimensional array FOO of S-expressions and with
subscripts -K ≤ i ≤ K:
(ARRAY FOO T (CONS (MINUS K) K))
*(EXARRAY "ID" TYPE B↓1 B↓2 ... B↓n) N ≤ 5.
EXARRAY is identical to ARRAY except that array elements are
stored in the body of a subroutine loaded by the LOADER (see Appendix
H), and exarray elements are not initialized. The array referencing
subroutine is stored in BINARY PROGRAM SPACE as with ARRAY. EXARRAY
searches symbol tables as does GETSYM (see Appendix H).
Note: Both ARRAY and EXARRAY consume BINARY PROGRAM SPACE. If
there is insufficient room there (see Appendix C) the error message
"BINARY PROGRAM SPACE EXCEEDED" will result.
(STORE ("ID" i↓1 i↓2 ... i↓n) value)
STORE changes the value of the specified array element to
value, and returns value.
Note: STORE evaluates its second argument first.
Examples: With the arrays declared previously:
(STORE (FOO 0) (QUOTE (A B)))
(STORE (FOO (BAZ L)) 1)
(STORE (A I J) (A J I))
(STORE (CHARS 1) 17)
15.1 Examine and Deposit
(EXAMINE N)
EXAMINE returns as an integer the contents of memory location
N.
(DEPOSIT N V)
DEPOSIT stores the integer V in memory location N and returns
V.
SAILON 28.7 CHAPTER 16 16-1
CHAPTER 16
OTHER FUNCTIONS
(TIME)
TIME returns the number of milliseconds your job has computed
since you logged into the system.
(ERRSET E "F")
ERRSET evaluates the S-expression E and if no error occurs
during its evaluation, ERRSET returns (LIST E). If an error occurs,
then the error message will be suppressed if and only if F ≠ NIL, and
NIL is returned as the value of ERRSET. If the function ERR is
called during evaluation, then no message is printed and ERRSET
returns the value returned by ERR.
The following example shows the use of ERRSET to keep trying
to initialize the line printer until it is available:
(DE LPTGRAB NIL
(PROG NIL
L (COND ((ATOM(ERRSET (OUTPUT LPT:) T))
(WAIT) (GO L)))))
where WAIT is some function (such as the time-sharing sleep UUO)
which causes a delay.
(ERR E)
ERR returns the value of E to the most recent ERRSET, or to
the top level of LISP if there is no ERRSET.
(*RSET X) flag = NIL initially
*RSET sets a special flag in the interpreter to the value of X, and
returns the previous value of the flag. Normally, with (*RSET NIL),
when an error occurs, special variables are restored to their top
level values from the special pushdown list, and the top level
READ-EVAL-PRINT loop is entered.
With (*RSET T), specials are not restored, neither pushdown
list is changed, and the READ-EVAL-PRINT loop is entered. This makes
it possible to examine the variable bindings immediately after an
error message has been printed. To restore special bindings to their
top level values and return to the top level, type a bell (π), or
evaluate (ERR).
(BAKGAG X)
SAILON 28.7 CHAPTER 16 16-2
BAKGAG sets a special flag in the interpreter to the value of
X and returns the previous setting of the flag. Only if the flag ≠
NIL when an error occurs, then a backtrace is printed as a series of
function calls, determined from the regular pushdown list, starting
from the most recent function call. If X is an integer, then X
specifies the number of regular pushdown list words to include the
backtrace. If X is T, then the entire regular pushdown list is
backtraced to the most recent ERRSET. The format for printing is:
printout meaning
fn1-fn2 Function 1 called function 2
fn1 - EVALARGS The arguments to fn1 are being
evaluated
before entering function 1.
fn1 - ENTER The function 1 is entered.
? - fn1 Some internal LISP function called
function 1.
Note: The BACKTRACE printout is often confused by compiled function
calls of the form (RETURN (FOO X)) which is compiled as
(JCALL (E FOO)) which can be changed to (JRST entrance to
FOO),
which will not show up in the BACKTRACE.
(INITFN FN)
INITFN selects the function of no arguments FN as an
initialization function which is evaluated after a LISP error return
to the top level has occurred or whenever a BELL is typed. INITFN
returns the previously selected initialization function.
Initialization functions are useful when it is desirable to
change the top level of LISP. For instance,
(INITFN (FUNCTION EVALQUOTE))
causes the top level to become EVALQUOTE instead of EVAL.
SAILON 28.7 APPENDIX A A-1
APPENDIX A
ALVINE
by John Allen
ALVINE is a LISP editor which is very convenient for
interactive debugging. ALVINE allows one to edit both function
definitions and S-expression values. ALVINE is characterized by the
simplicity with which one can correct a parenthesis mismatch and make
context searches and replacements. This simplicity arises from the
data structure ALVINE uses to represent an S-expression. All
S-expressions are flattened into a list of atoms including the atoms
%LP, %RP and %D which represent "(", ")" and ".". Because of this
representation, ALVINE looks more like a string type text editor with
the smallest unit of resolution being a single atom or S-expression
delimiter (%LP %RP or %D).
ALVINE has a pointer which can move through the string being
edited. The editing functions affect only the string to the right of
the pointer.
ALVINE also contains functions for manipulating input-output
files, and GRINDEF which is useful for printing function definitions.
ALVINE is not ordinarily a resident part of the LISP system,
but is automatically loaded whenever the function ED is called.
(ED X)
ED loads ALVINE if it is not already loaded. If X = NIL then
the editor is entered. If X = T, the editor is not entered. This is
useful to load GRINDEF without entering the editor.
From the top level of LISP, (ED) is the same as (ED NIL).
(SPRINT X Y 1)
SPRINT prints S-expression X in a special format which
automatically indents according to parenthesis level. Whenever any
sub-S-expression of X cannot fit entirely on the same printing line,
then its sub-S-expressions are printed on separate lines with
matching indentation. The parameter Y specifies the initial left
hand column indentation. SPRINT uses CHRCT and LINELENGTH to
determine the number of characters remaining on the print line.
(GRINDEF "F1" "F2" ... "Fn")
GRINDEF is used to print the definitions of functions and
values in DEFPROP format. GRINDEF uses SPRINT to print function
definitions in a highly readable format. GRINDEF prints all
SAILON 28.7 APPENDIX A A-2
properties of the identifiers F1, F2, ... Fn which are in the list
%%%L which is initialized to EXPR, FEXPR, VALUE, MACRO and SPECIAL.
Example: (GRINDEF PLUS)
(DEFPROP PLUS
(LAMBDA (L) (*EXPAND L (QUOTE *PLUS)))
MACRO)
Description of the Command Structure
Each command to ALVINE consists of a single character
(possibly preceded by a number) followed by a string of arguments.
These commands modify the text string presently occupying ALVINE's
buffer. When text is introduced to ALVINE a pointer is attached
preceding the first object in the buffer. ALVINE's commands allow
the user to move this pointer through the buffer. ALVINE's text
modifying commands only affect the string to the right of this
pointer.
In the following command descriptions, "pointer string" will
mean the string to the right of the pointer, and "$" will mean an
altmode. All of the commands which allow a repetition argument n
assume 1 if n is omitted.
COMMAND MEANING DESCRIPTION
A All Print the buffer string. No
attempt is made to make the
output pretty.
B Balanced? Examines the number of parens
in the buffer string. Returns
the count of left and right
parens if unbalanced; otherwise
replies "BAL".
nC Count For readability, the commands "D",
"M", ">", "<", "S", and "W", will
print an initial segment of the
pointer buffer. "nC" sets the
length of this printing segment
to n objects.
nD Delete Deletes the first n "objects"
to the right of the pointer.
nE Expunge Deletes the first n S-expressions
to the right of the pointer.
SAILON 28.7 APPENDIX A A-3
F x y:z File GRINDEFS the identifiers referred
to by x on device y using file
name z. If X is a list of identifiers,
then each element of x is GRINDEFed.
If x is an atom, then the value of
x is used as a list of atoms to
GRINDEF.
Gx Get G will convert an S-expression
with name x into ALVINE form, move
it into the ALVINE buffer and
initialize the pointer to the left
hand end of the buffer. GET looks
on the property list of x for the
first property in the list %%%L
which is initialized to (FEXPR
EXPR VALUE MACRO SPECIAL). %%%L
may be SETQed globally as desired.
G also knows about TRACEd functions
and will handle them properly.
ALVINE format was described earlier
as a single level list of atoms
including the special atoms %LP,
%RP, %D.
I Insert Insert comes in two flavors:
1. I$x$: insert "x" immediately
to the right of the pointer.
2. Ix$y$: insert "y" after the
first occurrence (in the pointer
string) of the string "x". "x"
may be a complete string or
described by ellipsis as "w...z".
If "x" is % then "y" is introduced
to the editor as the current
string.
nM Match Move the pointer n S-expressions
to the right of the current pointer
position. If n is negative, move n
S-expressions left. If there is no
such S-expression the pointer is not
moved and the bell is sounded.
Px Put Converts the editor string from
ALVINE format to an S-expression and
puts it back on the property list
of x with the appropriate property.
SAILON 28.7 APPENDIX A A-4
Qx <follows P> Same as P except no function name
need be specified. Q puts the
S-expression in the editor buffer
back on the property list of the
identifier the last G specified.
Rx$y$ Replace Replace the first occurrence of
"x" by "y". As with "I", "x" may
be described elliptically; and if
"y" is %, the first occurrence of
"x" is deleted.
nSx$ Search Search for the nth occurrence of
the string "x" (in the pointer
string). If found, the pointer is
moved to the beginning of the string
following that occurrence. If less
than n occurrences are located, the
pointer is positioned after the
last such occurrence. If none are
found the pointer is not moved.
If "x" is not given, i.e., "nS$",
then the last given search-string
is used.
Uxy:z Unfile READs and defines the functions
specified by the list x from
device y using z as a file name.
If x is an atom, then the value
of x is used as a list function
names to READ. U prints the names
of the functions as it defines them.
The specified file must be in
GRINDEF format.
V Vomit Print the first balanced paren
section to the right of the point
in pseudo GRINDEF format.
W Where? Prints the beginning of the pointer
string.
n> and n< These commands are dual; they move
the string pointer "n" objects to
the right or left respectively.
If "n" is such that either the left
or right end of the string would be
exceeded, the pointer is set to
that extreme and "bell" is typed.
To reset to the extreme left of
the string "0<" may be used.
SAILON 28.7 APPENDIX A A-5
This command returns control to
LISP. ALVINE's buffer is left
intact, and returning to ALVINE,
the user will find the pointer at
the left hand end of the old string.
Bell Bell may be used during any command
to return control to ALVINE's
command-listen-loop.
AN EXAMPLE OF ALVINE
Note: Bell, space and alt-mode are represented by π, _ and $ respectively.
(ED)
*
I % $(DEFPROP TEST (LAMBDA $; the string bounded by "$" is introduced to
ALVINE
*
A$
(DEFPROP TEST (LAMBDA ; print the entire ALVINE buffer
*
B$
2LPS
0 RPS
*
I LAMBDA $ (X) (CAR Y) EXPR) $; append the string bounded by "$" to the
buffer
*
B$
4LPS
3 RPS
*
I CAR Y $)$ ; add the deficient right paren
; the following commands
would also have the same effect:
; 1. "11<", "I $)$"
; 2. "SY$", I $)$
B$
BAL ;
$
V$
(DEFPROP TEST (LAMBDA (X) (CAR Y))EXPR)
*
P TEST$; convert ALVINE string to LISP function
*
↑ ; exit ALVINE
SAILON 28.7 APPENDIX A A-6
T$; now talking to LISP
T
(TEST (QUOTE(A B)))
Y
UNBOUND VARIABLE-EVAL ; LOSE
(ED) ; re-enter ALVINE,
*
W$
(DEFPROP TEST; "G" need not be executed since the buffer is always left intact.
*
R X $ Y$
*
P TSπ ; flush incorrect "put" command by typing bell. (π)
*
PTEST $ ; redefine TEST
*
↑
(TEST (QUOTE(A B)))$ ; try again
A ; win
(ED)
*
5 > $
(Y)
*
5C $ ; change print count
*
M $
(CAR Y))
*
E $
*
A $
(DEFPROP TEST (LAMBDA (Y))EXPR)
*
W $
)EXPR)
*
0 < $
π(DEFPROP TEST(
*
R TEST ...) $%$
*
A $
(DEFPROP)EXPR) ; same effect by:
1. "SDEFPROP $", "6D"
*
SAILON 28.7 APPENDIX B B-1
APPENDIX B
ERROR MESSAGES
The LISP interpreter checks for some error conditions and
prints messages accordingly. Many erroneous conditions are not
tested and result in either the wrong error message at some later
time, or no error message at all. In the latter case the system has
screwed you (or itself) without complaining.
When error messages are printed, it is usually difficult to
determine the function which caused the error and the functions which
called it. In this situation, (BAKGAG T) will turn on the BACKTRACE
flag which causes the heirarchy of function calls to be printed as
described in the next section.
The following is an alphabetical listing of error messages,
their cause, and in some cases, their remedy. Some error messages
print two lines, such as:
FOO
UNBOUND VARIABLE - EVAL
These messages are described last in the listing, and are of the
form:
X <message>
BINARY PROGRAM SPACE EXCEEDED
ARRAY, EXARRAY, or LAP has exceeded BINARY PROGRAM SPACE.
ALLOCATE more BPS next time.
CAN'T EXPAND CORE
INPUT, OUTPUT, LOAD, or ED failed to expand core. Your job
is too large.
CAN'T FIND FILE - INPUT
The input file was not found. You probably forgot to give
the file name extension, or a legal name list.
DEVICE NOT AVAILABLE
INPUT or OUTPUT found the specified device unavailable. Some
other job is probably using it.
DIRECTORY FULL
The directory of the output device is full.
SAILON 28.7 APPENDIX B B-2
DOT CONTEXT ERROR
READ does not like dots adjacent to parens or other dots.
FILE IS WRITE-PROTECTED
OUTPUT found that the specified file is write-protected.
FIRST ARGUMENT NON-ATOMIC - PUTPROP
An attempt was made to PUTPROP onto a non-identifier.
GARBAGED OBLIST
Some member of the OBLIST has been garbaged. You are in
trouble.
ILLEGAL DEVICE
INPUT or OUTPUT was attempted to either a non-existent device
or to a device of the wrong type. I.e., INPUT from the
lineprinter.
ILLEGAL OBJECT - READ
READ objects to syntactically incorrect S-expressions.
INPUT ERROR
Bad data was read from the selected device.
MORE THAN ONE S-EXPRESSION - MAKNAM
MAKNAM and READLIST object to a list which constitutes the
characters for more than one S-expression.
NO FREE STG LEFT
All free storage is bound to the OBLIST and protected cells
(such as list ARRAY cells), and bound variables on either the
REGULAR or SPECIAL pushdown list. Unbinding to the top level
will usually release the storage. If you are in a bind for
more free storage, try to REALLOC as described in APPENDIX C.
NO FULL WORDS LEFT
All full words are being used for print names and numbers.
The problem and its solution are similar to FREE STG.
NO I/O CHANNELS LEFT
SAILON 28.7 APPENDIX B B-3
INPUT or OUTPUT failed to find a free I/O channel. There is
a maximum of 14 active I/O channels.
NO INPUT - INC
n attempt was made to select a channel for input with INC
which was not initialized with INPUT.
NO LIST - MAKNAM
MAKNAM and READLIST object to an empty list.
NO OUTPUT - OUTC
An attempt was made to select a channel for output with OUTC
which was not initialized with OUTPUT.
NO PRINT NAME - INTERN
INTERN found a member of the OBLIST which has no print name.
You are in trouble.
OUTPUT ERROR
Data was improperly written on the selected output device.
Possibly a write-locked DECTAPE.
OVERFLOW
Some arithmetic function caused overflow - either fixed or
floating.
PDL OVERFLOW FROM GC - CAN'T CONTINUE
There is not enough regular pushdown list to finish garbage
collection. You lose. Try to REALLOC as described in
APPENDIX C.
READ UNHAPPY - MAKNAM
MAKNAM and READLIST object to a list which is not an entire
S-expression.
REG PUSHDOWN CAPACITY EXCEEDED SPEC PUSHDOWN CAPACITY EXCEEDED
A pushdown list has overflowed. This is usually caused by
non-termination of recursion. Sometimes you need to ALLOCATE
or REALLOC more pushdown list.
TOO FEW ARGUMENTS SUPPLIED - APPLY TOO MANY ARGUMENTS SUPPLIED -
APPLY
SAILON 28.7 APPENDIX B B-4
APPLY checks all calls on interpreted functions for the
proper number of arguments.
X MADE ILLEGAL MEMORY REFERENCE
The function X referred to an illegal address. Usually
caused by taking the CAR or CDR of an atom or number.
X NON-NUMERIC ARGUMENT
Arithmetic functions require that their arguments be numbers.
X PROGRAM TRAPPED FROM
An illegal instruction was executed in function X.
X UNBOUND VARIABLE - EVAL
EVAL tried to evaluate an identifier and found that it had no
value. You probably forgot to QUOTE some atom to initialize
it.
X UNDEFINED COMPUTED GO TAG IN
A GO in some compiled function had an undefined label.
X UNDEFINED FUNCTION X UNDEFINED FUNCTION - APPLY
The function X is not defined.
X UNDEFINED PROG TAG - GO
A GO in some interpreted function had an undefined label.
SAILON 28.7 APPENDIX C C-1
APPENDIX C
MEMORY ALLOCATION
The LISP 1.6 system has many different areas of memory for
storing data which can independently vary in size. Some LISP
applications demand larger allocations for these areas than others.
To allow users to adjust the sizes of these areas to their own needs,
a memory allocation procedure exists.
C.1 Summary of Storage Allocation Areas
BINARY PROGRAM SPACE Area for compiled functions and arrays.
FREE STORAGE Area for LISP nodes.
FULL WORD SPACE Area for print names and numbers.
BIT TABLES Area for the garbage collector.
REGULAR PUSHDOWN LIST Area for all function calls and non-
special variables in compiled functions.
SPECIAL PUSHDOWN LIST Area for interpreted variables and special
variables.
EXPANDED CORE Area for I/O buffers, ALVINE, LOADER, and
any loaded programs.
TOP OF CORE
_____________________________________
| |
| EXPANDED CORE |
|____________________________________|
| |
| SPECIAL PUSHDOWN LIST |
|____________________________________|
| |
Memory map | REGULAR PUSHDOWN LIST |
for the LISP |____________________________________|
1.6 system | |
| BIT TABLES |
|____________________________________|
| |
| FULL WORD SPACE |
|____________________________________|
| |
| FREE STORAGE |
|____________________________________|
| |
| BINARY PROGRAM SPACE |
|____________________________________|
| |
| LISP INTERPRETER |
|____________________________________|
BOTTOM OF CORE
SAILON 28.7 APPENDIX C C-2
C.2 ALLOCATION
When the LISP system is initially started, it asks the user
to specify the size of each of its various spaces as follows.
ALLOC?
FULL WDS=
BIN.PROG.SP=
SPEC.PDL=
REG. PDL=
HASH=
There are two basic responses to any of these questions:
1) A space will cause the default value to be used.
2) A number ended by a space cause the number to be used.
The default sizes of the later four spaces are 2000, 1000,
1000, and 77 octal words respectively. The default for full words is
400 octal plus a small fraction of free storage. Free storage is
thus allocated almost all of what is left.
C.3 REALLOC
If you have an existing LISP core image but have exhausted
one of the storage areas, it is possible to increase the size of that
area using the reallocation procedure. First, expand core with the
time sharing system command CORE and then re-enter the LISP core
image with the START command. For example, if the original core size
was 20K, you could increase it by 4K as follows:
↑C
.CORE 24
.START
*
When you reallocate a core image, all additional core is allocated
as follows:
1/4 for full word space
1/64 for each pushdown list,
the remainder to free storage and bit tables.
C.4 Binary Program Space
The reallocation procedure does not increase the size of
binary program space. However, it is possible to increase binary
program space by expanding core with the CORE (C) command and setting
BPORG and BPEND to the beginning and end of the expanded area of
core. For example, if you now have 32K of core and want 4K more BPS,
SAILON 28.7 APPENDIX C C-3
do the following:
(EXCISE) to eliminate IO buffers
↑C
.CORE 36
.START
*(SETQ BPORG (TIMES 32. 1024.))
*(SETQ BPEND (PLUS BPORG 4095.))
Note: If you use the reallocation procedure after having
expanded core for any purpose, it will reallocate this
additional core for its own purposes, thus destroying the
contents of the expanded core.
The following are the standard causes for expansion of core:
1) using I/O channels.
2) using the LOADER -(LOAD).
3) expanding core for more binary program space.
4) using (ED).
SAILON 28.7 APPENDIX D D-1
APPENDIX D
GARBAGE COLLECTION
All LISP systems have a function known as the garbage
collector. This function analyzes the entire state of list structure
which is pointed to by either the OBLIST, the regular pushdown list,
the special pushdown list, list arrays, and a few other special
cells. By recursively marking all words on free and full word
spaces which are pointed to in this manner, it is possible to
determine which words are not pointed to and are therefore garbage.
Such words are collected together on their respective free storage
lists.
(GC)
GC causes a garbage collection to occur and returns NIL.
Normally, a garbage collection occurs only when either free or full
word space has been exhausted.
(GCGAG X) flag = NIL initially.
GCGAG sets a special flag in the interpreter to the value of
X, and returns the previous setting of the flag. When any garbage
collection occurs, if the flag ≠ NIL, then the following is printed:
either FREE STORAGE EXHAUSTED
or FULL WORD SPACE EXHAUSTED
or nothing
followed by x FREE STORAGE, y FULL WORDS AVAILABLE
where x and y are numbers in octal.
(SPEAK)
SPEAK returns the total number of CONSes which have been
executed in this LISP core image.
(GCTIME)
GCTIME returns the number of milliseconds LISP has spent
garbage collecting in this core image.
It is possible to determine the lengths of the free and full
word free storage lists by:
(LENGTH (NUMVAL 15↓8)) = length of free storage list
(LENGTH (NUMVAL 16↓8)) = length of full word list
SAILON 28.7 APPENDIX E E-1
APPENDIX E
COMPILED FUNCTION LINKAGE AND ACCUMULATOR USAGE
This appendix is intended to explain the structure of
compiled functions, function calls, and accumulator usage. This
discussion is relevant only if one intends to interface hand coded
functions or possibly functions generated by another system (such as
FORTRAN) with the LISP system. In such a case, it is highly
recommended that one examine the LAP code generated by the LISP
compiler for some familiar functions.
ACCUMULATOR USAGE TABLE
s means "sacred" to the interpreter
p means "protected" during garbage collection
NIL = 0 s,p Header for the atom NIL.
A = 1 p Results from functions, 1st arg to
functions
B = 2 p 2nd arg
C = 3 p 3rd arg
AR1 = 4 p 4th arg
AR2A = 5 p 5th arg
T = 6 p used for LSUBR linkage
TT = 7 p
T10 = 10 p rarely used in the interpreter
S = 11 rarely used in the interpreter
D = 12
R = 13
P = 14 s,p regular pushdown list pointer
F = 15 s,p free storage list pointer
FF = 16 s,p full word list pointer
SP = 17 s,p special pushdown list pointer.
TEMPORARY STORAGE
Whenever a LISP function is called from a compiled function,
it is assumed that all accumulators from 2 through 13 are destroyed
by the function unless it is otherwise known. Therefore, local
variables and parameters in a compiled function should be saved in
some protected cells such as the regular pushdown list. The PUSH and
POP instructions are convenient for this purpose.
SPECIAL VARIABLE BINDINGS
Special variables in compiled functions are bound to special
cells by:
SAILON 28.7 APPENDIX E E-2
PUSHJ P, SPECBIND
0 n↓1, var↓1
0 n↓2, var↓2
...
start of function code.
SPECBIND saves the previous values of var↓i on the special pushdown
list and binds the contents of accumulator n↓i to each var↓i. The
var↓i must be pointers to special cells of identifiers. Any n↓i=0
causes the var↓i to be bound to NIL.
Special variables are restored to their previous values by:
PUSHJ P,SPECSTR
which stores the values previously saved on the special pushdown list
in the appropriate special cells.
NUMBERS
To convert the number in A from its LISP representation to
machine representation use:
PUSHJ P,NUMVAL
which returns the value of the number in A, and its type (either
FIXNUM or FLONUM) in B.
To convert the number in A from its machine representation to
LISP representation use either:
PUSHJ P,FIX1A for FIXNUMS
or PUSHJ P,MAKNUM with type in B.
Both of the above functions return the LISP number in A.
FUNCTION CALLING UUOS
To allow ease in linking, debugging, and modifying of
compiled functions, all compiled functions call other functions with
special opcodes called UUOs. Several categories of function calls
are distinguished:
1) Calls of the form (RETURN (FOO X)) are called terminal calls
and essentially "jump" to FOO.
2) Calls of the form (F X) where F is a computed function name
or functional argument is called a functional call.
The function calling UUOS are:
non-terminal terminal
SAILON 28.7 APPENDIX E E-3
non-functional CALL n,f JCALL n,f
functional CALLF n,f JCALLF n,f
where f is either the address of a compiled function or a pointer to
the identifier for the function, and n specifies the type of function
being called as follows:
n = 0 to 5 specifies a SUBR call with n arguments
n = 16 specifies a LSUBR call
n = 17 specifies a FSUBR call.
The function calling UUOs are defined in MACRO by:
OPDEF CALL [34B8]
OPDEF JCALL [35B8]
OPDEF CALLF [36B8]
OPDEF JCALLF [37B8]
(NOUUO X) flag = T initially
NOUUO sets a special flag in the compiled function calling
mechanism to the value of X and returns the previous setting of the
flag. Compiled functions initially call other functions with function
calling UUOs which "trap" into the UUO mechanism of the interpreter.
Ordinarily, such function calls involve searching the property list
of the function being called for the functional property, and then
(depending on whether the function is compiled or an S-expression)
the function is called.
If the NOUUO flag is set to NIL, then the overhead in calling
a compiled function from a compiled function can be eliminated by
replacing the CALL by PUSHJ and JCALL by JRST. CALLF and JCALLF are
never changed.
However, there are several dangers and restrictions when
using (NOUUO NIL). Once the UUO's have been replaced by PUSHJ's then
it is not possible to redefine or TRACE the function being called.
It is therefore recommended that compiled functions be debugged with
(NOUUO T).
SUBR LINKAGE
SUBRs are compiled EXPRs which are the most common type of
function. Consequently, considerable effort has been made to make
linkage to SUBRs efficient.
Arguments to SUBRs are supplied in accumulators 1 through n,
the first argument in 1. There is a maximum of 5 arguments to SUBRs.
To call a SUBR from compiled code, use call n,FUNC, where n
is the number of arguments, and call is the appropriate UUO.
SAILON 28.7 APPENDIX E E-4
The result from a SUBR is returned in A(= 1).
FSUBR LINKAGE
FSUBRs receive one argument in A and return their result in
A. FSUBRs which use the A-LIST feature call:
PUSHJ P, *AMAKE
which generates in B a number encoding the state of the special
pushdown pointer. To call a FSUBR, use call 17, FUNC, here call is
the appropriate UUO.
LSUBR LINKAGE
LSUBRs are similar to SUBRs except that they allow an
arbitrary number of arguments to be passed. To call a LSUBR, the
following sequence is used:
PUSH P, [ret] ;return address
PUSH P, arg1 ;1st argument
...
PUSH P, argn ;nth and last argument
MOVNI T,n ;minus number of arguments
call 16,func ;the appropriate UUO
ret: ;the LSUBR returns here
When a LSUBR is entered, it executes:
JSP 3,*LCALL
which initializes the LSUBR. A will contain n. The ith argument
can be referenced by:
MOVE A, -i-1(P)
Exit from an LSUBR with
POPJ P,
which returns to *LCALL to restore the stack.
SAILON 28.7 APPENDIX F F-1
APPENDIX F
THE LISP COMPILER
by Whitfield Diffie
The LISP compiler is a LISP program which transforms LISP
functions defined by S-expressions into LAP assembly code. This can
be loaded into binary program space by LAP (LISP Assembly Program), a
combined assembler and loader, which produces absolute machine code
in core.
Compiled functions are approximately twenty times as fast as
interpreted functions. Compiled functions also take up less memory
space and relieve the garbage collector from marking function
definitions. In a very large system of functions, this last point is
particularly significant.
The LISP compiler exists as the system program COMPLR, and is
called by the incantation `R COMPLR.' Once started, it is spoken to
in the same dialect as any other LISP.
USE OF THE COMPILER
(COMPL . "FILENAME - LIST")
The function COMPL takes as arguments an assortment of file
names and device names in precisely the same way as the function
DSKIN. The default device to be used for input in the event that
none is supplied in the argument sequence is given by the value of
the variable INDEV. There is no provision for specification of an
output device in the argument sequence. If the output is wanted on
some device other than the user's disk area, the variable OUTDEV must
be set to indicate this desire. All error messages and comments are
normally directed to the teletype. They can be sent to some other
device by setting the variable LISTING. Files produced by the
compiler have the filename extension LAP.
Examples:
(COMPL FOO SYS: TRACE)
will compile the file FOO from the users disk area
and the file TRACE from the system area to produce
the files FOO.LAP and TRACE.LAP on the users disk
area.
(SETQ INDEV (QUOTE DTA2:)) (SETQ OUTDEV (QUOTE (2,DAV)))
(SETQ LISTING (QUOTE (DSK: CMPMSG)))
(COMPL HAT SYS: SMILE)
SAILON 28.7 APPENDIX F F-2
will compile the file HAT from DTA2: and the file
SMILE from SYS: to produce the files HAT.LAP and
SMILE.LAP on the disk area [2,DAV]. All compiler
messages will appear as the file CMPMSG on the
user's disk area.
PREPARING FILES FOR COMPILATION
In preparing a file for compilation there are several things
that the user is well advised to bear in mind.
1) All normal function defining functions are acceptable to the
compiler. Functions defined by DE, DF, and DEFPROP, and macros
defined by DEFPROP or DM, will be correctly understood.
2) Any function which is unknown to the compiler when it is first
obliged to generate a call thereto, will be assumed to be an EXPR or
SUBR. If a file contains a function of any other type which is
called by a function defined earlier in the file, it must be declared
to the compiler with one of the statements: (DEFPROP fun T *FSUBR)
or (DEFPROP fun T *LSUBR) so that the compiler will know how to set
up its arguments.
3) Any variable which occurs free in any function must be declared
SPECIAL prior to the definition of any function which binds it.
This may be done with a statement of the form `(DEFPROP var T
SPECIAL).'
4) As macros are functions which are actually executed at compile
time, their definitions must occur earlier in the file than any
function which appeals to them. If this is not done, the macro will
be mistaken for an undefined EXPR.
COMPILER MESSAGES
As the compiler goes about its business, it will make various
comments and complaints about your code.
1) As the compilation of each function is completed, its name will be
typed on the teletype without carriage return. Any other message
will be stood off by carriage returns above and below.
2) Whenever the compiler discovers a free variable which has not been
declared special, it declares it. At the end of any function in
which it found such variables it will print out the message:
(SPECIAL var1 var2 etc.).
3) If a prog variable is unused in a function the compiler will print
the message (UNUSEDPROGVAR varname). It will also declare the
variable special on the theory that if it was not used there, it must
have been used somewhere else.
SAILON 28.7 APPENDIX F F-3
4) Many minor errors in user code will unfortunately go undetected.
Any serious error will produce the message *USER ERROR* followed by a
description of what was wrong. This will halt the compiler.
5) The error message *COMPILER ERROR* indicates a bug in the compiler.
Please report this to Whitfield Diffie.
6) When the compiler has finished, it will type out the name of the
file, the number of words of code produced and the time taken.
Following these will be lists of any functions called but not defined
in the file and any auxiliary functions the compiler generated.
USING COMPILED CODE
As LAP is self loading, the loading of compiled files is the
same as for interpreted functions. The allocations must be changed,
however, to reflect the passage of the code from free storage to
binary program space. The correct size of the latter is the size of
the program as stated at the end of compilation, plus the length of
lap which is about 500(8) words.
The following example illustrates various aspects of the
compiler's behavior. We show a collection of functions, the LAP
code generated from it, and the comments made by the compiler in the
process.
THE FUNCTIONS
(DM FIRST (L) (CONS @ CAR (CDR L))) ;macro defined at beginning
(DEFPROP IT T SPECIAL) ;special declaration
(DEFPROP MAPCONS ;the internal lambda
(LAMBDA (IT LIST) ;becomes a separate function
(MAPCAR (FUNCTION ;thus the variable IT must
(LAMBDA (X) ; be made special
(CONS IT X)))
LIST))
EXPR)
(DEFPROP COUNTM
(LAMBDA (SEXPR)
(PROG (COUNT) ;the variable COUNT has not been
(SETQ COUNT 0) ;declared special and will be treated
(COUNT1 SEXPR) ;as local
(RETURN COUNT)))
EXPR)
(DE COUNT1 (SS)
(COND ((ATOM SS) NIL)
(T (INCR COUNT) ;here it is discovered to be special
(COUNT1 (FIRST SS)) ;but too late
SAILON 28.7 APPENDIX F F-4
(COUNT1 (CDR SS)))))
(DE SCALE (NO) ;this variable is found to
(TIMES NO SCALEF)) ;be special, in good time
(DF SETQQ (L) (SET (CAR L) (CADR L)))
(SETQ SCALEF 3) ;this will be output unchanged
THE RESULTING LAP
;note that the macro definition and the special declaration have
;been gobbled up by the compiler.
(LAP MAPCONSG0220 SUBR) ;this is the function
(MOVE 2 (SPECIAL IT)) ;generated by the
(JCALL 2 (E XCONS)) ;internal lambda
NIL ;in MAPCONS
(LAP MAPCONS SUBR)
(JSP 6 SPECBIND)
(0 2 (SPECIAL IT))
(MOVEI 1 (QUOTE MAPCONSG0220))
(CALL 2 (E MAPCAR))
(JRST 0 SPECSTR)
NIL
(LAP COUNTM SUBR)
(PUSH P 1) ;this code is in error
(PUSH P (C 0 0 (QUOTE 0) 0)) ;due to the failure
(CALL 1 (E COUNT1)) ;to make COUNT special
(MOVE 1 0 P)
(SUB P (C 0 0 2 2))
(POPJ P)
NIL
(LAP COUNT1 SUBR)
(PUSH P 1)
(CALL 1 (E ATOM))
(JUMPE 1 G0229)
(MOVEI 1 (QUOTE NIL))
(JRST 0 G0228)
G0229 (MOVE 1 (SPECIAL COUNT)) ;reference to the special
(CALL 1 (E INCR)) ;variable COUNT, which has
(HLRZ@ 1 0 P) ;not been bound properly
(CALL 1 (E COUNT1))
(HRRZ@ 1 0 P)
(CALL 1 (E COUNT1))
G0228 (SUB P (C 0 0 1 1))
(POPJ P)
NIL
SAILON 28.7 APPENDIX F F-5
(LAP SCALE SUBR)
(MOVE 2 (SPECIAL SCALEF)) ;SCALEF is a free variable
(JCALL 2 (E *TIMES)) ;correctly detected
NIL
(LAP SETQQ FSUBR)
(HRRZ@ 2 1)
(HLRZ@ 2 2)
(HLRZ@ 1 1)
(JCALL 2 (E SET))
NIL
(SETQ SCALEF 3) ;this was unchanged by compilation
THE COMPILER'S OPINION
MAPCONSG0220 MAPCONS COUNTM
(SPECIAL COUNT) ;special found too late
COUNT1
(SPECIAL SCALEF) ;special found in time
SCALE SETQQ
(CMP . CMP) COMPILED 41 WORDS 3 CONSTANTS 1 SECONDS
UNDEFINED FUNCTIONS
INCR
GENERATED FUNCTIONS
MAPCONSG0220
SAILON 28.7 APPENDIX G G-1
APPENDIX G
THE LISP ASSEMBLER - LAP
LAP is a primitive assembler designed to load the output of the
compiler. Normally, it is not necessary to use LAP for any other purpose.
LAP is self loading.
The format of a compiled function in LAP is:
(LAP name type)
<sequence of LAP instructions>
NIL
where name is the name of the function, and type is either SUBR, LSUBR,
or FSUBR.
A LAP instruction is either:
1. A label which is a non-NIL identifier.
2. A list of the form
(OPCODE AC ADDR INDEX)
a. The index field is optional.
b. The opcode is either a PDP-6/10 instruction
which is defined to LAP and optionally suffixed
by @ which designates indirect addressing, or
a number which specifies a numerical opcode.
c. The AC and INDEX fields should contain a number
from 0 to 17, or P which designates register 14.
d. The ADDR field may be a number, a label, or a
list of one of the following forms:
(QUOTE S-expression) to reference list structure.
(SPECIAL x) to reference the value of
identifier x.
(E f) to reference the function f.
(C OPCODE AC ADDR INDEX) to reference a literal constant.
For example, the function ABS could be defined:
SAILON 28.7 APPENDIX G G-2
(LAP ABS SUBR)
(CALL 1 (E NUMVAL))
(MOVMS 0 1)
(JCALL 2(E MAKNUM))
NIL
SAILON 28.7 APPENDIX H H-1
APPENDIX H
THE LOADER
A modified version of the standard PDP-6/10
MACRO-FAIL-FORTRAN loader is available for use in LISP. One can call
the loader into a LISP core image at any time by executing:
(LOAD X)
When a * is typed, you are in the (LOAD X) loader, and the loader
command strings are expected. As soon as an altmode is typed, the
loader finishes and exits back to LISP.
The loader is placed in expanded core. If X = NIL then
loaded programs are placed in expanded core, otherwise (if X ≠ NIL)
they are placed in BINARY PROGRAM SPACE.
The loader removes itself and contracts core when it is
finished. In the following discussion a "RELOC" program will refer to
any program which is suitable for loading with the loader. The
output of FORTRAN, MACRO or FAIL is a RELOC program.
(EXCISE)
EXCISE contracts core to its length after ALLOCATION or the
last START. This removes I/O buffers, and all RELOC programs.
(*GETSYM S)
*GETSYM searches the DDT symbol table for the symbol S and if
found returns its value, otherwise it returns NIL.
(GETSYM "P" "S↓1" "S↓2" ... "S↓n")
GETSYM searches the DDT symbol table for each of the symbols S↓i
and places the value on the property list of S↓i under property P.
Example: (GETSYM SUBR DDT)
This causes DDT to be defined as a SUBR located at the value
of the symbol DDT.
Note: In order to load the symbol table, either /S or /D must be
typed to the loader. Symbols which are declared INTERNAL are
always in the symbol table without the /S or /D. In the case
of multiply defined symbols, i.e., a symbol used in more than
one RELOC program, a symbol declared INTERNAL takes
precedence, the last symbol otherwise.
(*PUTSYM S V)
SAILON 28.7 APPENDIX H H-2
*PUTSYM enters the symbol S into the DDT symbol table with
value V.
(PUTSYM "X↓1" "X↓2" ..."X↓n")
PUTSYM is used to place symbols in the DDT symbol table. If
X↓i is an atom then the symbol X↓i is placed in the symbol table with
its value pointing to the atom X↓i. If X↓i is a list, the symbol in
(CAR X↓i) is placed in the symbol table with its value (EVAL (CADR
X↓i)). PUTSYM is useful for making LISP atoms, functions, and
variables available to RELOC programs. Symbols must be defined with
PUTSYM before the LOADER is used.
Examples: (PUTSYM BPORG (VBPORG (GET (QUOTE BPORG)(QUOTE VALUE))))
defines the identifier BPORG and its value cell VBPORG. A RELOC
program can reference the value of BPORG by:
MOVE X,VBPORG
(PUTSYM (MAPLST (QUOTE MAPLST)) (NUMBERP (QUOTE NUMBERP)))
(PUTSYM (MEMQ (GET(QUOTE MEMQ) (QUOTE SUBR))))
A RELOC program would call these functions as follows:
CALL 2,MAPLST
CALL 1,NUMBRP
PUSHJ P,MEMQ or CALL 2,MEMQ
An example of a simple LISP compatible MACRO program to
compute square roots using the FORTRAN library.
TITLE TEST
P=14
A=1
B=2
EXTERN MAKNUM,NUMVAL,SQRT,FLONUM
LSQRT: CALL 1, NUMVAL
MOVEM A,AR1
MOVE A,[XWD 0,BLT1]; SAVE THE AC'S
BLT A,BLT1+17
JSA 16,SQRT
JUMP 2,AR1 ;SOP TO FORTRAN
MOVE 0,AR1
MOVE A,[XWD BLT1 ,0]
BLT A,17
MOVE A,AR1
MOVEI B,FLONUM
JCALL 2,MAKNUM
AR1: 0
SAILON 28.7 APPENDIX H H-3
BLT1: BLOCK 20
END
SAILON 28.7 APPENDIX I I-1
APPENDIX I
BIGNUMS - ARBITRARY PRECISION INTEGERS
LISP numbers have always been second class citizens, in the
sense that unlike strings (print names) numbers have had a maximum
length. In the PDP-6/10 LISP system there is an optional arbitrary
precision integer package which extends the length of LISP integers
from 36-bits to any length.
To load the BIGNUM system, execute the following at the top
level of LISP:
*(INC(INPUT SYS: (BIGNUM.LSP)))
<SEQUENCE OF OUTPUT>
*(LOAD T)*SYS:BIGNUM$
<LOADER TYPES BACK>
*(APNINIT)
and then your core image will perform arbitrary precision integer
operations using the standard LISP arithmetic functions which were
redefined by APNINIT.
It is possible to load the BIGNUM package at any time unless
you have already executed compiled functions with (NOUUO NIL), in
which case you must reconstruct your core image.
SAILON 28.7 APPENDIX J J-1
A USER MODIFIABLE LISP SCANNER
by Lynn Quam
LISP uses a table driven scanner, whose table may be modified
by the user for the purpose of implementing scanners for other
languages. For simplicity, the functions for constructing the scanner
table initially give an ALGOL type scanner, that is the ALGOL
definitions for identifiers, strings and numbers (except for powers
of ten). The ALGOL table may be modified by using additional
functions to include additional characters in identifiers, and to
specify delimiters for strings.
J.1 FORMAL DEFINITIONS
J.1.1 Identifiers
Syntax:
comment ::= (a comment-start followed by any sequence of
characters ending in a comment-end)
digit ::= "0" | "1" | ... | "9"
letter ::= "A" | "B" | ... | "Z" | "a" | "b" | ... | "z" |
extra-letter
character ::= (any ASCII character other than null, rubout,
and comment-start)
delimiter ::= (any character not a letter and not a digit)
::= letter
::= identifier digit
::= identifier letter
::= slashified character
::= identifier slashified character
Semantics:
In the above syntax, underlined symbols can be specified by
the user. For instance, comment-start and comment-end could both be
specified to be double quote ("). If it is desirable to include
dollar and percent signs in identifiers, then both of these
characters should be extra-letters. Slashifiers make it possible to
include any delimiter in an identifier. For example, if question
mark is the slashifier (?) and it is desirable to include the
character (+) in the identifier V as V+, then one should slashify the
plus: V?+.
J.1.2 Strings
Syntax:
string ::= (a string-start followed by any sequence of
characters ending in a string-end)
SAILON 28.7 APPENDIX J J-2
Semantics:
String-start and string-end are specifiable.
J.1.3 Numbers
Syntax:
Same as specified in Chapter 4, except that leading signs (+
or -) in numbers are treated as delimiters.
J.2 DESCRIPTIONS OF THE SCANNER MODIFYING FUNCTIONS
In the following descriptions, all characters are specified
by their numerical ASCII value. For example, in octal, blank is 40
and A is 101.
(SCANINIT comment-start comment-end string-start string-end slashifier)
SCANINIT modifies the LISP scanner to be an ALGOL-type
scanner with special delimiters for comments and strings. SCANINIT
must be called before any of the other scanner functions.
(IGNORE x)
LETTER specifies to the scanner that x is not to be returned
as a delimiter from scan, but instead will be ignored. However, x
will still function as a separator between identifier and numbers.
For example, carriage-return, line-feed, tab and blank are useful
characters to ignore as delimiters.
(LETTER X)
Letter specifies to the scanner that X is an extra-letter,
and thus allows X to be in an identifier.
(SCAN)
SCAN reads an atom or delimiter and sets the value of the
global variable SCANVAL to the value read, and returns a number
corresponding to the syntactic type read as follows:
Syntactic type Value of SCAN Value of SCNVAL
identifier 0 the uninterned identifier
string 1 the string
number 2 the value
delimiter 3 the ASCII value of the
delimiter.
(SCANSET)
SCANSET modifies the LISP scanner in READ according to the
user specifications. Evaluate (SCANSET) before calling SCAN.
SAILON 28.7 APPENDIX J J-3
(SCANRESET)
SCANRESET unmodifies the LISP scanner to its normal state,
and must be called before READ will work properly again once SCANSET
is used. Use INITFN to call SCANSET after errors.
J.3 USING THE MODIFIABLE SCANNER
The scanner modifying functions are not a normal part of the
LISP system and must be explicitly loaded into a LISP core image.
The following steps indicate how to provide the proper interface
between LISP and the scanner, load the scanner, and initialize the
scanner tables.
(SETQ SCNVAL NIL)
(PUTSYM (SCNVAL (GET (QUOTE SCNVAL)(QUOTE VALUE))))
(LOAD) SYS:SCAN$
(GETSYM SUBR SCANINIT LETTER IGNORE SCAN SCANSET
SCANRESET)
(SCANINIT 21 73 42 42 45)
<this makes comments start with ⊃ and with semicolon,
strings start and end with double quotes ("), and
percent (%) is the slashifier>
To use the scanner, one must first call the SCANSET. Once
SCANSET has been called, the normal LISP function READ no longer
behaves in a normal fashion, since READ will now use the modified
scanner tables. Care must be taken to call SCANRESET before calling
READ.
SAILON 28.7 APPENDIX K K-1
APPENDIX K
SOS-LINK
by Whitfield Diffie
The SOSLINK program is an aid to debugging interpreted LISP
functions, which allows rapid turnaround in the `test-edit-test' loop
of debugging. It is famous for the two functions FILEIN and EDFUN
which behave as follows.
(FILEIN . "FILENAME-LIST")
The way in which this function takes its arguments differs
only from DSKIN in that all files must come from the user's own disk
area.
When a file is loaded with FILEIN, information is saved for
each function defined in the file telling what file it came from and
on what page and line it was defined. Initially, this information
will only be saved for atoms which are defined to be EXPRS, FEXPRS,
or MACROS. If the user wishes to have it saved for some other
property, for example VALUES, he can achieve this effect by putting
the property SWAPIT on the property list of the indicator he wished
to have so honored, in this case by putting the property SWAPIT on
the property list of the indicator VALUE.
(EDFUN "FUN" "PROP")
This function is used in the environment created by FILEIN.
It will call in the system editor, SOS, with its attention focused on
the function FUN. At the same time, it will save a copy of the
user's LISP and prepare for a quick return to this copy. Once the
editor has been started the function definition may be edited in the
usual way. It should be noted, however, that although edits may be
made to other parts of the file, only the definition of FUN will be
loaded on return to LISP.
If FUN has more that one property for which file information
is being saved, it may be necessary to use the second argument PROP
of EDFUN in order to specify which one is desired.
When editing has been finished, and a return to LISP is
wanted, it is only necessary to type the command G to SOS. A saved
copy of the user's LISP will be started and the single function
definition which is modified will be reloaded.
As long as no global modifications are made to the file, this
process may be repeated indefinitely. Such actions as renumbering
the file are discouraged, however.
SAILON 28.7 APPENDIX L L-1
APPENDIX L
SOME DIFFERENCES BETWEEN THIS AND OTHER LISPS
by Whitfield Diffie
1) The top level of this system does not use EVALQUOTE as do many
systems. However, EVALQUOTE may be defined as follows:
(DE EVALQUOTE NIL
(PROG NIL
L (TERPRI)
(PRINT (EVAL (CONS (READ) (MAPCAR
(FUNCTION (LAMBDA (X) (LIST (QUOTE QUOTE) X)))
(READ)))))
(GO L)))
The top level of LISP 1.6 is equivalent to:
(PROG NIL
L (TERPRI)
(PRINT (EVAL (READ)))
(GO L))
2) The order of the arguments in the various functions
MAP, MAPCAR etc. is function first, list second,
rather that the reverse as in many systems.
3) There are certain differences even between Stanford
Lisp and other DEC system Lisps.
a) the comment character is ascii 32
b) project programmer numbers are pairwords
in which each half holds up to three
right adjusted sixbit characters.
c) The new debugging package depends on system
features only available in the Stanford system.
This debugging package is described in Appendix K.
SAILON 28.7 APPENDIX M M-1
APPENDIX M
LISP Display Primitives
by Lynn Quam
A set of display primitives are now available for LISP users.
These primitives use the features in the D. Poole display service
subsystem. Users should be familiar with section II.D.8 of Sailon
55, and SAILON 29.
The following display primitives allow the user to enter
display commands into "the" current display buffer. The contents of
this buffer are not seen until the user executes the "SHOW"
primitive.
(AIVECT X Y) draws an absolute invisible vector to (X,Y).
(AVECT X Y) draws an absolute visible vector to (X,Y).
(APT X Y) draws an endpoint vector to (X,Y).
(RIVECT X Y) draws a relative invisible vector to (X,Y).
(RVECT X Y) draws a relative visible vector to (X,Y).
(RPT X Y) draws a relative endpoint vector to (X,Y).
(GVECT X Y OP SIZE BRT) assembles display processor opcode <OP>
with X, Y, SIZE, BRT fields specified.
E.g., (GVECT 0 0 46 1 0) draws a zero length
invisible vector and sets the character size to 1.
(LOCATE) returns the position of the last word put
in the display buffer.
(DJUMP N) stores a display processor jump to location n.
(DJSR N) stores a display processor subroutine call to
location n.
(FIXUP X Y) stores y into the jump (or JSR) address at
location x.
All of the above commands return the referred to display buffer
address.
(SHOW N) the current display buffer is displayed on
"piece of glass" (N).
(KILL N) erases "piece of glass" (N).
(CLEAR) erases the current display buffer.
(DTYOS) selects the display buffer for character
output from LISP. (TYO, PRINT, ETC.)
SAILON 28.7 APPENDIX M M-2
(DTYOU) unselects character output to the display buffer.
DTYOS and DTYOU make it possible to define a printing function:
(DE DPRINC (L) (PROG NIL (DTYOS) (PRINC L) (DTYOU) (RETURN L)))
(CHINIT CHSIZ LINELENGTH LEFTMARGIN)
initializes internal parameters for DTYOS so that
text will be displayed with size <CHSIZE> and with
line length and left margin specified.
To use these primitives, use the following loading sequence:
(INC(INPUT SYS: (LISPDP.LSP)))
<sequence of output>
(LOAD <NIL or T>)
*SYS:LISPDP$
<loader output>
*(DISPINIT)
<now you can use the display>
SAILON 28.7 APPENDIX N N-1
APPENDIX N
TRACE
by Lynn Quam and Whitfield Diffie
I. FUNCTIONS FOR DEBUGGING FUNCTIONS
Three different types of debugging aids are available: TRACE,
TRACET and BREAK.
A) TRACE and its auxiliary functions UNTRACE and RESET allow one to
monitor the entrance to and exit from "traced" functions. (Warning:
use (NOUUO T) with compiled functions) when a "traced" function is
entered.
(ENTERING <recursion depth> <function name>) <values of
arguments> is typed. When exited,
(LEAVING <recursion depth> <function name>) <result> is
typed.
(TRACE <list of names>) FEXPR causes all functions in list of names
to be "traced". TRACE returns a list of names of those
functions which were previously not traced.
(UNTRACE <list of names>) FEXPR is the inverse to TRACE, i.e., it
restores each function to its previous untraced state.
(RESET) EXPR causes all recursion depth counters to be reset to
zero. Only necessary when a traced function is abnormally
exited.
B) TRACET and its auxiliary functions UNTRACET SLST and USLST allow
one to monitor all SET's or SETQ's to atoms selected for by SLST.
When such a SET or SETQ occurs,
SET <atom name> <value>) or
SETQ <atom name> <value>)
is printed. (Warning - use (NOUUO T) with compiled functions)
(TRACET) EXPR turns on SET-SETQ monitoring.
(UNTRACET) EXPR turns off SET-SETQ monitoring.
(SLST <list of atoms>) FEXPR appends <list of atoms> to the list of
monitored atoms.
(USLST <list of atoms> removes each atom from list of monitored
atoms.
SAILON 28.7 APPENDIX N N-2
C) (BREAK <comment> <expression>) FEXPR is useful for observing
the state of variable bindings within lambda expressions
and progs. When BREAK is entered, (BREAK . <comment>)
is printed. BREAK then enters a READ-EVAL-PRINT loop
until an atom which is the value of the atom *BPROCEED*
is typed to READ. This atom will initially be P>, but may
be changed by setting the value of *BPROCEED*. BREAK then
exits with <value>.
SAILON 28.7 APPENDIX O O-1
APPENDIX O
SMILE
by Lynn Quam and Whitfield Diffie
I. FUNCTIONS FOR USING OUTPUT DEVICES
(LPT) EXPR is used to start an output file on the line printer.
It does
(PROG NIL (OUTC (OUTPUT LPT:) T)
(LINELENGTH LPTLENGTH)
(OUTTIME))
where OUTTIME prints a heading, time and date.
(OFF) EXPR is used to end an output file. It does
(PROG NIL (PRINT T)
(OUTC NIL T)
(LINELENGTH TTYLENGTH))
(LPTOUT <expr-list>) FEXPR is used to create an entire output
file on the lineprinter. It does
(PROG NIL (LPT)
(MAPC (FUNCTION EVAL) <expr-list>)
(OFF))
Examples: (LPTOUT (GRINL ALLFNS))
(LPTOUT (PRINT OBLIST) (PRINT FOO))
(DSKOUT <file name> <expr-list>) FEXPR is used to create an
entire output file on disk file DSK: <file-name>.LSP.
It sets linelength to LPTLENGTH, and evaluates all
expressions in <expr-list>, then does (OFF).
Example: (DSKOUT NEWFNS (GRINL NEWFNS))
II. OTHER USEFUL FUNCTIONS
(GRINL <atom>) FEXPR causes all atoms in the list (<atom>
<value of atom>) to be GRINDEFed.
For example, (GRINL ALLFNS) will cause ALLFNS and every function
which has been defined by DE, DF, or DM to be GRINDEFed.
GRINDEF uses the auxiliary functions SPRINT, HUNOZ, PANL,
and PPOS.
SAILON 28.7 APPENDIX O O-2
(GETDEF <device name> <file name> <list of function names>)
FEXPR needs selected function definitions from
specified disk file, and prints the names of
those found. GETDEF returns ***.
Example: (GETDEF DSK: NEWFNS SIZE FOOBAZ)
(TIMER <expression list>) FEXPR returns the execution time
in milliseconds of the expressions in the
expression list.
Example: (TIMER (GC) (GC)) returns the number
of milliseconds necessary to do 2 garbage
collections.
(EDIT <atom> <old> <new>) FEXPR causes all occurrences of <old>
s-expression to be replaced by <new> s-expression
in some property of <atom>. The property to
change is selected as follows:
(1) EXPR
(2) FEXPR
(3) first property on property list.
Example: (EDIT OFF TTYLENGTH 105)
Would charge OFF to:
(DEFPROP OFF
(LAMBDA NIL (PROG NIL (PRINT T) (OUTC NIL T)
(LINELENGTH 105))) EXPR)
EDIT returns T if a change was made. Otherwise NIL.
SAILON 28.7 APPENDIX P P-1
APPENDIX P
CONSTRUCTION OF A LISP DISK-DECTAPE SYSTEM
by Lynn Quam and Whitfield Diffie
LIST OF FILES, TYPES AND DESTINATIONS
FILES TYPE DESTINATION
LISP.MAC MACRO STEPS 2,5 LISP.DMP
LOADER.MAC MACRO STEPS 3,5 LISP.LOD
SYMMAK.MAC MACRO STEPS 4,5 LISP.SYM
ALVINE.MAC MACRO STEP 6 LISP.ED
LISP.LSP LISP STEP 5 LISP.LSP
COMPLR LISP STEPS 8,9 COMPLR.CMP
LAP LISP STEP 5 LAP
SMILE LISP STEP 5 SMILE
GRIN LISP STEP 5 GRIN
TRACE LISP STEP 5 TRACE
DISK DECTAPE
The following conventions
will be made:
DTAS = dectape where system
will be created
DTAI = dectape where source
files are
DTAT = dectape for temporary
files
Also, make the following
assignment:
.ASSIGN DTAS: DSK:
SAILON 28.7 APPENDIX P P-2
1) Assemble with MACRO-10
LISP.REL←LISP.MAC DTAT:LISP.REL←DTAI:LISP.MAC
LOADER.REL←LOADER.MAC DTAT:LOADER.REL←DTAI:LOADER.MAC
SYMMAK.REL←SYMMAK.MAC DTAT:SYMMAK.REL←DTAI:SYMMAK.MAC
ALVINE.REL←ALVINE.MAC DTAT:ALVINE.REL←DTAI:ALVINE.MAC
2) To generate the LISP INTERPRETER
.R LOADER<cr>
*LISP<alt> *DTAT:LISP<alt>
↑C
.SAVE DSK:LISP 10<cr> .SAVE DTAS:LISP 10<cr>
3) To generate the LISP LOADER
.R LOADER<cr>
*LOADER<alt> *DTAT:LOADER<alt>
↑C
.START<cr>
<This creates the mode 17 file DSK:LISP.LOD or DTAS:LISP.LOD>
4) To generate the LISP LOADER SYMBOL TABLE
.R LOADER<cr>
*DSK:LISP/J,DSK:SYMMAK<alt> *DTAT:LISP/J,DTAT:SYMMAK<alt>
↑C
.START<cr>
<This creates the file DSK:LISP.SYM> or <DTAT:LISP.SYM>
5) Copy to DSK or DTAS the following files:
LISP.LSP, SMILE, GRIN, TRACE, and LAP
Now if using DECTAPE do: .ASSIGN DTAS: SYS:
SAILON 28.7 APPENDIX P P-3
6) To generate ALVINE
.R LISP<cr>
ALLOC? N
(DSKIN (ALVINE.LSP))<cr> *(DSKIN DTAI: (ALVINE.LSP))<cr>
* (LOAD)<cr> * (LOAD)<cr>
* ALVINE <alt> * DTAT: ALVINE <alt>
* (GETSYM SUBR ALVINE)<cr>
* (ALVINE)<cr>
<This creates the file DSK: LISP.ED> or <DTAS: LISP.ED>
Copy the file LISP.ED to SYS
7) To compile the LISP compiler:
7a) If there is an older revision of the compiler, do
.R COMPLR<cr>
and go to step 8.
7b) If there is not an older version of the compiler, do
.R LISP 34<cr>
ALLOC? N
*(DSKIN COMPLR)<cr> *(DSKIN DTAI: COMPLR)<cr>
<this loads everything>
and go to step 8.
8) Actual compilation of the LISP COMPILER
* (SETQ INDEV (QUOTE DTAI:))<cr>
* (SETQ OUTDEV (QUOTE DTAT:))<cr>
* (COMPL COMPLR)<cr>
<random messages>
↑C
SAILON 28.7 APPENDIX P P-4
<This generates the file DSK: COMPLR.LAP> or <DTAT: COMPLR.LAP>.
9) To load the compiled LISP COMPILER,
.R LISP 30<cr>
ALLOC? Y
FULL. WDS=3000<sp>
BIN.PROG.SP=14300<sp>
SPEC.PDL=<sp>
REG. PDL=<sp>
HASH=475<sp>
*(DSKIN (COMPLR.LAP))<cr> *(DSKIN DTAT: (COMPLR.LAP))<cr>
* (CINIT)<cr>
↑C
.SAVE DSK: COMPLR<cr> .SAVE DTAS: COMPLR<cr>
Copy the file COMPLR.DMP to SYS:
SAILON 28.7 REFERENCES REF-1
REFERENCES
1. John McCarthy, et al., LISP 1.5 Programmer's Manual
(Cambridge, Mass., MIT Press, 1962).
2. Clark Weissman, LISP 1.5 Primer, (Dickenson Publishing
Co., 1967).
3. Robert A. Saunders, "LISP - On the Programming System",
in Edmond C. Berkley and Daniel G. Bobrow (eds.),
The Programming Language LISP: Its Operation and
Applications, 2nd edition, (Cambridge, Mass., The
MIT Press, 1966), p.54.
SAILON 28.7 INDEX IND-1
INDEX
ABS SUBR . . . . . . . . . . . . . . . . 12-1
ADD1 SUBR . . . . . . . . . . . . . . . . 12-1
ALIST . . . . . . . . . . . . . . . . 7-3
AND FSUBR . . . . . . . . . . . . . . . . 9-3
APPEND LSUBR n arguments . . . . . . . . . . 10-1
APPLY LSUBR . . . . . . . . . . . . . . . . 7-1
ARG SUBR . . . . . . . . . . . . . . . . 6-2
ARRAY FSUBR different . . . . . . . . . . . 15-1
ASCII SUBR . . . . . . . . . . . . . . . . 11-3
ASSOC SUBR uses EQ . . . . . . . . . . . . 10-6
ATOM SUBR . . . . . . . . . . . . . . 3-1,9-1
BAKGAG SUBR initialized to T . . . . . . . 16-1
BASE VALUE initialized to 8 . . . . . . . 4-1
BIGNUM . . . . . . . . . . . . . . . I,4-2
BOOLE LSUBR . . . . . . . . . . . . . . . . 12-3
BPEND VALUE top of binary program space . . C-3
BPORG VALUE bottom of binary program space. C-4
BREAK FEXPR . . . . . . . . . . . . . . . . N-2
CAR SUBR . . . . . . . . . . . . . . . . 10-2
CDR SUBR . . . . . . . . . . . . . . . . 10-2
... ... . . . . . . . . . . . . . . . .
CAAAAR SUBR . . . . . . . . . . . . . . . . 10-2
CDDDDR SUBR . . . . . . . . . . . . . . . . 10-2
CHRCT SUBR . . . . . . . . . . . . . . . . 14-5
COND FSUBR allows more than one consequent 8-1
CONS SUBR . . . . . . . . . . . . . . . . 10-1
CSYM FSUBR . . . . . . . . . . . . . . . . 11-3
DDTIN SUBR . . . . . . . . . . . . . . . . 14-3
DDTOUT SUBR . . . . . . . . . . . . . . . . 14-5
DE FSUBR . . . . . . . . . . . . . . . . 11-2
DEFPROP FSUBR . . . . . . . . . . . . . . . . 11-2
DEPOSIT SUBR . . . . . . . . . . . . . . . . 15-2
DF FSUBR . . . . . . . . . . . . . . . . 11-2
DIFFERENCE MACRO n arguments . . . . . . . . . . 12-1
DIVIDE SUBR . . . . . . . . . . . . . . . . 12-1
DM FSUBR . . . . . . . . . . . . . . . . 11-2
DSKIN FEXPR . . . . . . . . . . . . . . . .14-2a
ED SUBR . . . . . . . . . . . . . . . . A-1
EDFUN FEXPR . . . . . . . . . . . . . . . . K-1
EQ SUBR . . . . . . . . . . . . . . . . 9-1
EQUAL SUBR . . . . . . . . . . . . . . . . 9-1
ERR SUBR . . . . . . . . . . . . . . . . 16-1
ERRSET FSUBR . . . . . . . . . . . . . . . . 16-1
EVAL LSUBR second argument allowed . . . . 7-1
EXAMINE SUBR . . . . . . . . . . . . . . . . 15-2
EXARRAY FSUBR . . . . . . . . . . . . . . . . 15-2
EXCISE SUBR . . . . . . . . . . . . . . . . H-1
EXPLODE SUBR . . . . . . . . . . . . . . . . 10-7
EXPLODEC SUBR . . . . . . . . . . . . . . . . 10-7
SAILON 28.7 INDEX IND-2
EXPR . . . . . . . . . . . . . . . . 6-2
FEXPR . . . . . . . . . . . . . . . . 6-2
FILEIN FEXPR . . . . . . . . . . . . . . . . K-1
FILENAMES . . . . . . . . . . . . . . . . 14-1
FIX SUBR . . . . . . . . . . . . . . . . 12-2
FIX1A SYM . . . . . . . . . . . . . . . . E-2
FIXNUM . . . . . . . . . . . . . . . . 4-2
FLATSIZE SUBR . . . . . . . . . . . . . . . . 10-7
FLONUM . . . . . . . . . . . . . . . . 4-3
FORCE SUBR . . . . . . . . . . . . . . . . 14-5
FSUBR . . . . . . . . . . . . . . . . E-4
FUNARG . . . . . . . . . . . . . . . . 7-4
FUNCTION FSUBR . . . . . . . . . . . . . . . . 7-1
FUNCTIONAL ARGUMENTS . . . . . . . . . . . . . . . 7-1
GC SUBR . . . . . . . . . . . . . . . . D-1
GCD SUBR . . . . . . . . . . . . . . . . 12-1
GCGAG SUBR . . . . . . . . . . . . . . . . D-1
GCTIME SUBR . . . . . . . . . . . . . . . . D-1
GENSYM SUBR . . . . . . . . . . . . . . . . 11-3
GET SUBR . . . . . . . . . . . . . . . . 11-1
GETL SUBR . . . . . . . . . . . . . . . . 11-1
GETSYM FEXPR . . . . . . . . . . . . . . . . H-1
GO FSUBR . . . . . . . . . . . . . . . . 13-1
GREATERP MACRO n arguments . . . . . . . . . . 9-3
GRINDEF FSUBR . . . . . . . . . . . . . . . . A-1
IBASE VALUE initialized to 8 . . . . . . . 4-1
IDENTIFIER . . . . . . . . . . . . . . . . 3-1
INC SUBR . . . . . . . . . . . . . . . . 14-2
INITFN SUBR . . . . . . . . . . . . . . . . 16-1
INPUT FSUBR . . . . . . . . . . . . . . . . 14-1
INTEGER . . . . . . . . . . . . . . . . 4-1
INTERN SUBR . . . . . . . . . . . . . . . . 11-2
LABEL . . . . . . . . . . . . . . . . 6-1
LAMBDA . . . . . . . . . . . . . . . . 6-1
LAST SUBR returns end of list . . . . . . 10-2
LENGTH SUBR . . . . . . . . . . . . . . . . 10-4
LESSP MACRO n arguments . . . . . . . . . . 9-3
LEXPR . . . . . . . . . . . . . . . . 6-2
LINELENGTH SUBR . . . . . . . . . . . . . . . . 14-5
LIST FSUBR . . . . . . . . . . . . . . . . 10-1
LOAD SUBR . . . . . . . . . . . . . . . . H-1
LSH SUBR . . . . . . . . . . . . . . . . 12-3
LSUBR . . . . . . . . . . . . . . . . E-4
MACRO . . . . . . . . . . . . . . . . 6-3
MAKNAM SUBR . . . . . . . . . . . . . . . . 10-7
MAKNUM SUBR . . . . . . . . . . . . . . . . E-2
MAP SUBR different argument order. . . . 10-5
MAPC SUBR " " " . . . 10-5
MAPCAR SUBR " " " . . . 10-6
MAPLIST SUBR " " " . . . 10-5
MEMBER SUBR uses EQUAL . . . . . . . . . . 9-2
MEMQ SUBR uses EQ . . . . . . . . . . . . 9-2
SAILON 28.7 INDEX IND-3
MINUS SUBR . . . . . . . . . . . . . . . . 12-1
MINUSP SUBR . . . . . . . . . . . . . . . . 9-2
NCONC LSUBR . . . . . . . . . . . . . . . . 10-3
NCONS SUBR . . . . . . . . . . . . . . . . 10-1
NIL VALUE initialized to NIL . . . . . . 5-1
NOT SUBR . . . . . . . . . . . . . . . . 9-3
NOUUO SUBR initialized to T . . . . . . . E-3
NULL SUBR . . . . . . . . . . . . . . . . 9-2
NUMBER . . . . . . . . . . . . . . . . 4-1
NUMBERP SUBR . . . . . . . . . . . . . . . . 9-2
NUMVAL SUBR . . . . . . . . . . . . . . . . E-2
OBLIST VALUE . . . . . . . . . . . . . . . . 3-3
OR FSUBR . . . . . . . . . . . . . . . . 9-3
OUTC SUBR . . . . . . . . . . . . . . . . 14-4
OUTPUT FSUBR . . . . . . . . . . . . . . . . 14-4
PGLINE SUBR . . . . . . . . . . . . . . . . 14-2
PLUS MACRO n arguments . . . . . . . . . . 12-1
PNAME . . . . . . . . . . . . . . . . 3-2
PRIN1 SUBR allows non-atomic S-expressions 14-5
PRINC SUBR . . . . . . . . . . . . . . . . 14-5
PRINT SUBR TERPRI first . . . . . . . . . 14-6
PROG FSUBR . . . . . . . . . . . . . . . . 13-1
PROG2 SUBR allows up to 5 arguments. . . . 13-1
PROPERTY LIST . . . . . . . . . . . . . . . . 3-2
PUTPROP SUBR order of arguments different 11-1
PUTSYM FEXPR . . . . . . . . . . . . . . . . H-2
QUOTE FSUBR . . . . . . . . . . . . . . . . 7-1
QUOTIENT MACRO n arguments . . . . . . . . . . 12-1
READ SUBR . . . . . . . . . . . . . . . . 14-3
READCH SUBR . . . . . . . . . . . . . . . . 14-4
READLIST SUBR . . . . . . . . . . . . . . . . 10-7
REMAINDER SUBR . . . . . . . . . . . . . . . . 12-1
REMOB FSUBR . . . . . . . . . . . . . . . . 11-2
REMPROP SUBR . . . . . . . . . . . . . . . . 11-1
RESET EXPR . . . . . . . . . . . . . . . .
RETURN SUBR . . . . . . . . . . . . . . . . 13-1
REVERSE SUBR . . . . . . . . . . . . . . . . 10-4
RPLACA SUBR . . . . . . . . . . . . . . . . 10-3
RPLACD SUBR . . . . . . . . . . . . . . . . 10-3
SASSOC SUBR uses EQ . . . . . . . . . . . . 10-6
SET SUBR . . . . . . . . . . . . . . . . 11-2
SETARG SUBR . . . . . . . . . . . . . . . . 6-3
SETQ FSUBR . . . . . . . . . . . . . . . . 11-2
SEXPRESSION . . . . . . . . . . . . . . . . 5-1
SPEAK SUBR . . . . . . . . . . . . . . . . D-1
SPECBIND SYM . . . . . . . . . . . . . . . . E-2
SPECSTR SYM . . . . . . . . . . . . . . . . E-2
SPECIAL not in interpreter . . . . . . F-1
SPECIAL VARIABLES . . . . . . . . . . . . . . . . 7-3
SPRINT SUBR . . . . . . . . . . . . . . . . A-1
STORE FSUBR . . . . . . . . . . . . . . . . 15-2
STRING . . . . . . . . . . . . . . . . 3-3
SAILON 28.7 INDEX IND-4
SUB1 SUBR . . . . . . . . . . . . . . . . 12-1
SUBR . . . . . . . . . . . . . . . . E-3
SUBST SUBR . . . . . . . . . . . . . . . . 10-4
T VALUE initialized to T . . . . . . . 9-1
TERPRI SUBR . . . . . . . . . . . . . . . . 14-6
TIME SUBR . . . . . . . . . . . . . . . . 16-1
TIMES MACRO n arguments . . . . . . . . . . 12-1
TRACE FEXPR . . . . . . . . . . . . . . . . N-1
TRACET EXPR . . . . . . . . . . . . . . . . N-1
TYI SUBR . . . . . . . . . . . . . . . . 14-4
TYO SUBR . . . . . . . . . . . . . . . . 14-6
VALUE . . . . . . . . . . . . . . . . 3-2
VARIABLE BINDINGS . . . . . . . . . . . . . . . . 7-2
XCONS SUBR . . . . . . . . . . . . . . . . 10-1
ZEROP SUBR . . . . . . . . . . . . . . . . 9-2
$EOF$ . . . . . . . . . . . . . . . . 14-2
*AMAKE SYM . . . . . . . . . . . . . . . . E-4
*APPEND SUBR . . . . . . . . . . . . . . . . 10-1
*DIF SUBR . . . . . . . . . . . . . . . . 12-1
*EVAL SUBR . . . . . . . . . . . . . . . . 7-1
*EXPAND SUBR . . . . . . . . . . . . . . . . 6-4
*EXPAND1 SUBR . . . . . . . . . . . . . . . . 6-4
*FUNCTION FSUBR . . . . . . . . . . . . . . . . 7-4
*GETSYM SUBR . . . . . . . . . . . . . . . . H-1
*GREAT SUBR . . . . . . . . . . . . . . . . 9-3
*LCALL SYM . . . . . . . . . . . . . . . . E-4
*LESS SUBR . . . . . . . . . . . . . . . . 9-3
*NOPOINT VALUE initialized to NIL . . . . . . 4-1
*PLUS SUBR . . . . . . . . . . . . . . . . 12-1
*PUTSYM SUBR . . . . . . . . . . . . . . . . H-2
*QUO SUBR . . . . . . . . . . . . . . . . 12-1
*RSET SUBR initialized to NIL . . . . . . 16-1
*TIMES SUBR . . . . . . . . . . . . . . . . 12-1